void QOpenGLTextureBlitterPrivate::blit(GLuint texture, const QMatrix4x4 &vertexTransform, const QMatrix3x3 &textureTransform) { TextureBinder binder(texture); prepareProgram(vertexTransform); program->setUniformValue(textureTransformUniformPos, textureTransform); textureMatrixUniformState = User; QOpenGLContext::currentContext()->functions()->glDrawArrays(GL_TRIANGLES, 0, 6); }
/** @brief Iterate Functional Test cases. * * @return Iteration result. */ tcu::TestCase::IterateResult TextureCubeMapArrayETC2Support::iterate(void) { prepareFramebuffer(); prepareProgram(); prepareVertexArrayObject(); prepareTexture(); draw(); if (isRenderedImageValid()) m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); else m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); clean(); return STOP; }
void QOpenGLTextureBlitterPrivate::blit(GLuint texture, const QMatrix4x4 &vertexTransform, QOpenGLTextureBlitter::Origin origin) { TextureBinder binder(texture); prepareProgram(vertexTransform); if (origin == QOpenGLTextureBlitter::OriginTopLeft) { if (textureMatrixUniformState != IdentityFlipped) { QMatrix3x3 flipped; flipped(1,1) = -1; flipped(1,2) = 1; program->setUniformValue(textureTransformUniformPos, flipped); textureMatrixUniformState = IdentityFlipped; } } else if (textureMatrixUniformState != Identity) { program->setUniformValue(textureTransformUniformPos, QMatrix3x3()); textureMatrixUniformState = Identity; } QOpenGLContext::currentContext()->functions()->glDrawArrays(GL_TRIANGLES, 0, 6); }
int main() { if(glfwInit() == GL_FALSE) { std::cerr << "Failed to initialize GLFW" << std::endl; return -1; } defer(glfwTerminate()); glfwDefaultWindowHints(); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_SAMPLES, 4); GLFWwindow* window = glfwCreateWindow(800, 600, "Models", nullptr, nullptr); if(window == nullptr) { std::cerr << "Failed to open GLFW window" << std::endl; return -1; } defer(glfwDestroyWindow(window)); glfwMakeContextCurrent(window); if(glxwInit()) { std::cerr << "Failed to init GLXW" << std::endl; return -1; } glfwSwapInterval(1); glfwSetWindowSizeCallback(window, windowSizeCallback); glfwShowWindow(window); bool errorFlag = false; std::vector<GLuint> shaders; GLuint vertexShaderId = loadShader("shaders/vertexShader.glsl", GL_VERTEX_SHADER, &errorFlag); if(errorFlag) { std::cerr << "Failed to load vertex shader (invalid working directory?)" << std::endl; return -1; } shaders.push_back(vertexShaderId); GLuint fragmentShaderId = loadShader("shaders/fragmentShader.glsl", GL_FRAGMENT_SHADER, &errorFlag); if(errorFlag) { std::cerr << "Failed to load fragment shader (invalid working directory?)" << std::endl; return -1; } shaders.push_back(fragmentShaderId); GLuint programId = prepareProgram(shaders, &errorFlag); if(errorFlag) { std::cerr << "Failed to prepare program" << std::endl; return -1; } defer(glDeleteProgram(programId)); glDeleteShader(vertexShaderId); glDeleteShader(fragmentShaderId); // === prepare textures === GLuint textureArray[3]; int texturesNum = sizeof(textureArray)/sizeof(textureArray[0]); glGenTextures(texturesNum, textureArray); defer(glDeleteTextures(texturesNum, textureArray)); GLuint grassTexture = textureArray[0]; GLuint skyboxTexture = textureArray[1]; GLuint towerTexture = textureArray[2]; if(!loadDDSTexture("textures/grass.dds", grassTexture)) return -1; if(!loadDDSTexture("textures/skybox.dds", skyboxTexture)) return -1; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if(!loadDDSTexture("textures/tower.dds", towerTexture)) return -1; // === prepare VAOs === GLuint vaoArray[3]; int vaosNum = sizeof(vaoArray)/sizeof(vaoArray[0]); glGenVertexArrays(vaosNum, vaoArray); defer(glDeleteVertexArrays(vaosNum, vaoArray)); GLuint grassVAO = vaoArray[0]; GLuint skyboxVAO = vaoArray[1]; GLuint towerVAO = vaoArray[2]; // === prepare VBOs === GLuint vboArray[6]; int vbosNum = sizeof(vboArray)/sizeof(vboArray[0]); glGenBuffers(vbosNum, vboArray); defer(glDeleteBuffers(vbosNum, vboArray)); GLuint grassVBO = vboArray[0]; GLuint skyboxVBO = vboArray[1]; GLuint towerVBO = vboArray[2]; GLuint grassIndicesVBO = vboArray[3]; GLuint skyboxIndicesVBO = vboArray[4]; GLuint towerIndicesVBO = vboArray[5]; // === load models === GLsizei grassIndicesNumber, skyboxIndicesNumber, towerIndicesNumber; GLenum grassIndexType, skyboxIndexType, towerIndexType; if(!modelLoad("models/grass.emd", grassVAO, grassVBO, grassIndicesVBO, &grassIndicesNumber, &grassIndexType)) return -1; if(!modelLoad("models/skybox.emd", skyboxVAO, skyboxVBO, skyboxIndicesVBO, &skyboxIndicesNumber, &skyboxIndexType)) return -1; if(!modelLoad("models/tower.emd", towerVAO, towerVBO, towerIndicesVBO, &towerIndicesNumber, &towerIndexType)) return -1; glm::mat4 projection = glm::perspective(70.0f, 4.0f / 3.0f, 0.3f, 250.0f); GLint matrixId = glGetUniformLocation(programId, "MVP"); GLint samplerId = glGetUniformLocation(programId, "textureSampler"); auto startTime = std::chrono::high_resolution_clock::now(); auto prevTime = startTime; glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // hide cursor Camera camera(window, glm::vec3(0, 0, 5), 3.14f /* toward -Z */, 0.0f /* look at the horizon */); glEnable(GL_DOUBLEBUFFER); glEnable(GL_CULL_FACE); glEnable(GL_MULTISAMPLE); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glClearColor(0, 0, 0, 1); glUniform1i(samplerId, 0); while(glfwWindowShouldClose(window) == GL_FALSE) { if(glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) break; if(glfwGetKey(window, GLFW_KEY_Z) == GLFW_PRESS) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } if(glfwGetKey(window, GLFW_KEY_X) == GLFW_PRESS) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } auto currentTime = std::chrono::high_resolution_clock::now(); float startDeltaTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - startTime).count(); float prevDeltaTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - prevTime).count(); prevTime = currentTime; float rotationTimeMs = 100000.0f; float currentRotation = startDeltaTimeMs / rotationTimeMs; float islandAngle = 360.0f*(currentRotation - (long)currentRotation); glm::mat4 view; camera.getViewMatrix(prevDeltaTimeMs, &view); glm::mat4 vp = projection * view; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(programId); glm::mat4 towerMVP = vp * glm::rotate(islandAngle, 0.0f, 1.0f, 0.0f) * glm::translate(-1.5f, -1.0f, -1.5f); glBindTexture(GL_TEXTURE_2D, towerTexture); glBindVertexArray(towerVAO); glUniformMatrix4fv(matrixId, 1, GL_FALSE, &towerMVP[0][0]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, towerIndicesVBO); glDrawElements(GL_TRIANGLES, towerIndicesNumber, towerIndexType, nullptr); glm::mat4 grassMVP = vp * glm::rotate(islandAngle, 0.0f, 1.0f, 0.0f) * glm::translate(0.0f, -1.0f, 0.0f); glBindTexture(GL_TEXTURE_2D, grassTexture); glBindVertexArray(grassVAO); glUniformMatrix4fv(matrixId, 1, GL_FALSE, &grassMVP[0][0]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, grassIndicesVBO); glDrawElements(GL_TRIANGLES, grassIndicesNumber, grassIndexType, nullptr); glm::vec3 cameraPos; camera.getPosition(&cameraPos); glm::mat4 skyboxMatrix = glm::translate(cameraPos) * glm::scale(100.0f,100.0f,100.0f); glm::mat4 skyboxMVP = vp * skyboxMatrix; // TODO: implement modelDraw procedure (or maybe Model object?) glBindTexture(GL_TEXTURE_2D, skyboxTexture); glBindVertexArray(skyboxVAO); glUniformMatrix4fv(matrixId, 1, GL_FALSE, &skyboxMVP[0][0]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, skyboxIndicesVBO); glDrawElements(GL_TRIANGLES, skyboxIndicesNumber, skyboxIndexType, nullptr); glfwSwapBuffers(window); glfwPollEvents(); } return 0; }
int main() { if(glfwInit() == GL_FALSE) { std::cerr << "Failed to initialize GLFW" << std::endl; return -1; } defer(glfwTerminate()); glfwDefaultWindowHints(); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_SAMPLES, 4); GLFWwindow* window = glfwCreateWindow(800, 600, "Lighting", nullptr, nullptr); if(window == nullptr) { std::cerr << "Failed to open GLFW window" << std::endl; return -1; } defer(glfwDestroyWindow(window)); glfwMakeContextCurrent(window); if(glxwInit()) { std::cerr << "Failed to init GLXW" << std::endl; return -1; } glfwSwapInterval(1); glfwSetWindowSizeCallback(window, windowSizeCallback); glfwShowWindow(window); bool errorFlag = false; std::vector<GLuint> shaders; GLuint vertexShaderId = loadShader("shaders/vertexShader.glsl", GL_VERTEX_SHADER, &errorFlag); if(errorFlag) { std::cerr << "Failed to load vertex shader (invalid working directory?)" << std::endl; return -1; } shaders.push_back(vertexShaderId); GLuint fragmentShaderId = loadShader("shaders/fragmentShader.glsl", GL_FRAGMENT_SHADER, &errorFlag); if(errorFlag) { std::cerr << "Failed to load fragment shader (invalid working directory?)" << std::endl; return -1; } shaders.push_back(fragmentShaderId); GLuint programId = prepareProgram(shaders, &errorFlag); if(errorFlag) { std::cerr << "Failed to prepare program" << std::endl; return -1; } defer(glDeleteProgram(programId)); glDeleteShader(vertexShaderId); glDeleteShader(fragmentShaderId); // === prepare textures === GLuint textureArray[6]; int texturesNum = sizeof(textureArray)/sizeof(textureArray[0]); glGenTextures(texturesNum, textureArray); defer(glDeleteTextures(texturesNum, textureArray)); GLuint grassTexture = textureArray[0]; GLuint skyboxTexture = textureArray[1]; GLuint towerTexture = textureArray[2]; GLuint garkGreenTexture = textureArray[3]; GLuint redTexture = textureArray[4]; GLuint blueTexture = textureArray[5]; if(!loadDDSTexture("textures/grass.dds", grassTexture)) return -1; if(!loadDDSTexture("textures/skybox.dds", skyboxTexture)) return -1; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if(!loadDDSTexture("textures/tower.dds", towerTexture)) return -1; loadOneColorTexture(0.05f, 0.5f, 0.1f, garkGreenTexture); loadOneColorTexture(1.0f, 0.0f, 0.0f, redTexture); loadOneColorTexture(0.0f, 0.0f, 1.0f, blueTexture); // === prepare VAOs === GLuint vaoArray[5]; int vaosNum = sizeof(vaoArray)/sizeof(vaoArray[0]); glGenVertexArrays(vaosNum, vaoArray); defer(glDeleteVertexArrays(vaosNum, vaoArray)); GLuint grassVAO = vaoArray[0]; GLuint skyboxVAO = vaoArray[1]; GLuint towerVAO = vaoArray[2]; GLuint torusVAO = vaoArray[3]; GLuint sphereVAO = vaoArray[4]; // === prepare VBOs === GLuint vboArray[10]; int vbosNum = sizeof(vboArray)/sizeof(vboArray[0]); glGenBuffers(vbosNum, vboArray); defer(glDeleteBuffers(vbosNum, vboArray)); GLuint grassVBO = vboArray[0]; GLuint grassIndicesVBO = vboArray[1]; GLuint skyboxVBO = vboArray[2]; GLuint skyboxIndicesVBO = vboArray[3]; GLuint towerVBO = vboArray[4]; GLuint towerIndicesVBO = vboArray[5]; GLuint torusVBO = vboArray[6]; GLuint torusIndicesVBO = vboArray[7]; GLuint sphereVBO = vboArray[8]; GLuint sphereIndicesVBO = vboArray[9]; // === load models === GLsizei grassIndicesNumber, skyboxIndicesNumber, towerIndicesNumber, torusIndicesNumber, sphereIndicesNumber; GLenum grassIndexType, skyboxIndexType, towerIndexType, torusIndexType, sphereIndexType; if(!modelLoad("models/grass.emd", grassVAO, grassVBO, grassIndicesVBO, &grassIndicesNumber, &grassIndexType)) return -1; if(!modelLoad("models/skybox.emd", skyboxVAO, skyboxVBO, skyboxIndicesVBO, &skyboxIndicesNumber, &skyboxIndexType)) return -1; if(!modelLoad("models/tower.emd", towerVAO, towerVBO, towerIndicesVBO, &towerIndicesNumber, &towerIndexType)) return -1; if(!modelLoad("models/torus.emd", torusVAO, torusVBO, torusIndicesVBO, &torusIndicesNumber, &torusIndexType)) return -1; if(!modelLoad("models/sphere.emd", sphereVAO, sphereVBO, sphereIndicesVBO, &sphereIndicesNumber, &sphereIndexType)) return -1; glm::mat4 projection = glm::perspective(70.0f, 4.0f / 3.0f, 0.3f, 250.0f); GLint uniformMVP = getUniformLocation(programId, "MVP"); GLint uniformM = getUniformLocation(programId, "M"); GLint uniformTextureSample = getUniformLocation(programId, "textureSampler"); GLint uniformCameraPos = getUniformLocation(programId, "cameraPos"); GLint uniformMaterialSpecularFactor = getUniformLocation(programId, "materialSpecularFactor"); GLint uniformMaterialSpecularIntensity = getUniformLocation(programId, "materialSpecularIntensity"); GLint uniformMaterialEmission = getUniformLocation(programId, "materialEmission"); auto startTime = std::chrono::high_resolution_clock::now(); auto prevTime = startTime; Camera camera(window, glm::vec3(0, 0, 5), 3.14f /* toward -Z */, 0.0f /* look at the horizon */); glEnable(GL_DOUBLEBUFFER); glEnable(GL_CULL_FACE); glEnable(GL_MULTISAMPLE); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glClearColor(0, 0, 0, 1); glUseProgram(programId); glUniform1i(uniformTextureSample, 0); bool directionalLightEnabled = true; bool pointLightEnabled = true; bool spotLightEnabled = true; bool wireframesModeEnabled = false; float lastKeyPressCheck = 0.0; const float keyPressCheckIntervalMs = 250.0f; setupLights(programId, directionalLightEnabled, pointLightEnabled, spotLightEnabled); while(glfwWindowShouldClose(window) == GL_FALSE) { if(glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) break; auto currentTime = std::chrono::high_resolution_clock::now(); float startDeltaTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - startTime).count(); float prevDeltaTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - prevTime).count(); prevTime = currentTime; float rotationTimeMs = 100000.0f; float currentRotation = startDeltaTimeMs / rotationTimeMs; float islandAngle = 360.0f*(currentRotation - (long)currentRotation); if(startDeltaTimeMs - lastKeyPressCheck > keyPressCheckIntervalMs) { if(glfwGetKey(window, GLFW_KEY_X) == GLFW_PRESS) { lastKeyPressCheck = startDeltaTimeMs; wireframesModeEnabled = !wireframesModeEnabled; if(wireframesModeEnabled) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); else glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } if(glfwGetKey(window, GLFW_KEY_M) == GLFW_PRESS) { lastKeyPressCheck = startDeltaTimeMs; bool enabled = camera.getMouseInterception(); camera.setMouseInterception(!enabled); } if(glfwGetKey(window, GLFW_KEY_1) == GLFW_PRESS) { lastKeyPressCheck = startDeltaTimeMs; directionalLightEnabled = !directionalLightEnabled; setupLights(programId, directionalLightEnabled, pointLightEnabled, spotLightEnabled); } if(glfwGetKey(window, GLFW_KEY_2) == GLFW_PRESS) { lastKeyPressCheck = startDeltaTimeMs; pointLightEnabled = !pointLightEnabled; setupLights(programId, directionalLightEnabled, pointLightEnabled, spotLightEnabled); } if(glfwGetKey(window, GLFW_KEY_3) == GLFW_PRESS) { lastKeyPressCheck = startDeltaTimeMs; spotLightEnabled = !spotLightEnabled; setupLights(programId, directionalLightEnabled, pointLightEnabled, spotLightEnabled); } } glm::vec3 cameraPos; camera.getPosition(&cameraPos); glUniform3f(uniformCameraPos, cameraPos.x, cameraPos.y, cameraPos.z); glm::mat4 view; camera.getViewMatrix(prevDeltaTimeMs, &view); glm::mat4 vp = projection * view; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // TODO implement ModelLoader and Model classes // tower glm::mat4 towerM = glm::rotate(islandAngle, 0.0f, 1.0f, 0.0f) * glm::translate(-1.5f, -1.0f, -1.5f); glm::mat4 towerMVP = vp * towerM; glBindTexture(GL_TEXTURE_2D, towerTexture); glBindVertexArray(towerVAO); glUniformMatrix4fv(uniformMVP, 1, GL_FALSE, &towerMVP[0][0]); glUniformMatrix4fv(uniformM, 1, GL_FALSE, &towerM[0][0]); glUniform1f(uniformMaterialSpecularFactor, 1.0f); glUniform1f(uniformMaterialSpecularIntensity, 0.0f); glUniform3f(uniformMaterialEmission, 0.0f, 0.0f, 0.0f); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, towerIndicesVBO); glDrawElements(GL_TRIANGLES, towerIndicesNumber, towerIndexType, nullptr); // torus glm::mat4 torusM = glm::translate(0.0f, 1.0f, 0.0f) * glm::rotate((60.0f - 3.0f*islandAngle), 0.0f, 0.5f, 0.0f); glm::mat4 torusMVP = vp * torusM; glBindTexture(GL_TEXTURE_2D, garkGreenTexture); glBindVertexArray(torusVAO); glUniformMatrix4fv(uniformMVP, 1, GL_FALSE, &torusMVP[0][0]); glUniformMatrix4fv(uniformM, 1, GL_FALSE, &torusM[0][0]); glUniform1f(uniformMaterialSpecularFactor, 1.0f); glUniform1f(uniformMaterialSpecularIntensity, 1.0f); glUniform3f(uniformMaterialEmission, 0.0f, 0.0f, 0.0f); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, torusIndicesVBO); glDrawElements(GL_TRIANGLES, torusIndicesNumber, torusIndexType, nullptr); // grass glm::mat4 grassM = glm::rotate(islandAngle, 0.0f, 1.0f, 0.0f) * glm::translate(0.0f, -1.0f, 0.0f); glm::mat4 grassMVP = vp * grassM; glBindTexture(GL_TEXTURE_2D, grassTexture); glBindVertexArray(grassVAO); glUniformMatrix4fv(uniformMVP, 1, GL_FALSE, &grassMVP[0][0]); glUniformMatrix4fv(uniformM, 1, GL_FALSE, &grassM[0][0]); glUniform1f(uniformMaterialSpecularFactor, 32.0f); glUniform1f(uniformMaterialSpecularIntensity, 2.0f); glUniform3f(uniformMaterialEmission, 0.0f, 0.0f, 0.0f); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, grassIndicesVBO); glDrawElements(GL_TRIANGLES, grassIndicesNumber, grassIndexType, nullptr); // skybox glm::mat4 skyboxM = glm::translate(cameraPos) * glm::scale(100.0f,100.0f,100.0f); glm::mat4 skyboxMVP = vp * skyboxM; glBindTexture(GL_TEXTURE_2D, skyboxTexture); glBindVertexArray(skyboxVAO); glUniformMatrix4fv(uniformMVP, 1, GL_FALSE, &skyboxMVP[0][0]); glUniformMatrix4fv(uniformM, 1, GL_FALSE, &skyboxM[0][0]); glUniform1f(uniformMaterialSpecularFactor, 1.0f); glUniform1f(uniformMaterialSpecularIntensity, 0.0f); glUniform3f(uniformMaterialEmission, 0.0f, 0.0f, 0.0f); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, skyboxIndicesVBO); glDrawElements(GL_TRIANGLES, skyboxIndicesNumber, skyboxIndexType, nullptr); // point light source if(pointLightEnabled) { glm::mat4 pointLightM = glm::translate(pointLightPos); glm::mat4 pointLightMVP = vp * pointLightM; glBindTexture(GL_TEXTURE_2D, redTexture); glBindVertexArray(sphereVAO); glUniformMatrix4fv(uniformMVP, 1, GL_FALSE, &pointLightMVP[0][0]); glUniformMatrix4fv(uniformM, 1, GL_FALSE, &pointLightM[0][0]); glUniform1f(uniformMaterialSpecularFactor, 1.0f); glUniform1f(uniformMaterialSpecularIntensity, 1.0f); glUniform3f(uniformMaterialEmission, 0.5f, 0.5f, 0.5f); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sphereIndicesVBO); glDrawElements(GL_TRIANGLES, sphereIndicesNumber, sphereIndexType, nullptr); } // spot light source if(spotLightEnabled) { glm::mat4 spotLightM = glm::translate(spotLightPos); glm::mat4 spotLightMVP = vp * spotLightM; glBindTexture(GL_TEXTURE_2D, blueTexture); glBindVertexArray(sphereVAO); glUniformMatrix4fv(uniformMVP, 1, GL_FALSE, &spotLightMVP[0][0]); glUniformMatrix4fv(uniformM, 1, GL_FALSE, &spotLightM[0][0]); glUniform1f(uniformMaterialSpecularFactor, 1.0f); glUniform1f(uniformMaterialSpecularIntensity, 1.0f); glUniform3f(uniformMaterialEmission, 0.5f, 0.5f, 0.5f); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sphereIndicesVBO); glDrawElements(GL_TRIANGLES, sphereIndicesNumber, sphereIndexType, nullptr); } glfwSwapBuffers(window); glfwPollEvents(); } return 0; }
int main() { if(glfwInit() == GL_FALSE) { std::cerr << "Failed to initialize GLFW" << std::endl; return -1; } defer(std::cout << "Calling glfwTerminate()" << std::endl; glfwTerminate()); glfwDefaultWindowHints(); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); GLFWwindow* window = glfwCreateWindow(800, 600, "Rotating cube", nullptr, nullptr); if(window == nullptr) { std::cerr << "Failed to open GLFW window" << std::endl; return -1; } defer(std::cout << "Calling glfwDestroyWindow()" << std::endl; glfwDestroyWindow(window)); glfwMakeContextCurrent(window); if(glxwInit()) { std::cerr << "Failed to init GLXW" << std::endl; return -1; } glfwSwapInterval(1); glfwSetWindowSizeCallback(window, windowSizeCallback); glfwShowWindow(window); bool errorFlag = false; std::vector<GLuint> shaders; GLuint vertexShaderId = loadShader("shaders/vertexShader.glsl", GL_VERTEX_SHADER, &errorFlag); if(errorFlag) { std::cerr << "Failed to load vertex shader (invalid working directory?)" << std::endl; return -1; } shaders.push_back(vertexShaderId); GLuint fragmentShaderId = loadShader("shaders/fragmentShader.glsl", GL_FRAGMENT_SHADER, &errorFlag); if(errorFlag) { std::cerr << "Failed to load fragment shader (invalid working directory?)" << std::endl; return -1; } shaders.push_back(fragmentShaderId); GLuint programId = prepareProgram(shaders, &errorFlag); if(errorFlag) { std::cerr << "Failed to prepare program" << std::endl; return -1; } defer(glDeleteProgram(programId)); glDeleteShader(vertexShaderId); glDeleteShader(fragmentShaderId); GLuint vertexVBO; glGenBuffers(1, &vertexVBO); defer(glDeleteBuffers(1, &vertexVBO)); glBindBuffer(GL_ARRAY_BUFFER, vertexVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(globVertexBufferData), globVertexBufferData, GL_STATIC_DRAW); GLuint colorVBO; glGenBuffers(1, &colorVBO); defer(glDeleteBuffers(1, &colorVBO)); glBindBuffer(GL_ARRAY_BUFFER, colorVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(globColorBufferData), globColorBufferData, GL_STATIC_DRAW); GLuint vao; glGenVertexArrays(1, &vao); defer(glDeleteVertexArrays(1, &vao)); glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vertexVBO); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glBindBuffer(GL_ARRAY_BUFFER, 0); // unbind VBO glBindBuffer(GL_ARRAY_BUFFER, colorVBO); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glBindBuffer(GL_ARRAY_BUFFER, 0); // unbind VBO glBindVertexArray(0); // unbind VAO glm::mat4 projection = glm::perspective(80.0f, 4.0f / 3.0f, 0.3f, 100.0f); GLint matrixId = glGetUniformLocation(programId, "MVP"); auto startTime = std::chrono::high_resolution_clock::now(); auto prevTime = startTime; // hide cursor glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); Camera camera(window, glm::vec3(0, 0, 5), 3.14f /* toward -Z */, 0.0f /* look at the horizon */); glEnable(GL_DOUBLEBUFFER); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glDepthFunc(GL_LESS); glClearColor(0, 0, 0, 1); while(glfwWindowShouldClose(window) == GL_FALSE) { if(glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) break; if(glfwGetKey(window, GLFW_KEY_Z) == GLFW_PRESS) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } if(glfwGetKey(window, GLFW_KEY_X) == GLFW_PRESS) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } auto currentTime = std::chrono::high_resolution_clock::now(); float startDeltaTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - startTime).count(); float prevDeltaTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - prevTime).count(); prevTime = currentTime; float rotationTimeMs = 3000.0f; float currentRotation = startDeltaTimeMs / rotationTimeMs; float angle = 360.0f*(currentRotation - (long)currentRotation); glm::mat4 view; camera.getViewMatrix(prevDeltaTimeMs, &view); glm::mat4 model = glm::rotate(angle, 0.0f, 1.0f, 0.0f); glm::mat4 mvp = projection * view * model; // matrix multiplication is the other way around glUniformMatrix4fv(matrixId, 1, GL_FALSE, &mvp[0][0]); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(programId); glBindVertexArray(vao); glEnableVertexAttribArray(0); // could be done once before while loop ... -> glEnableVertexAttribArray(1); glDrawArrays(GL_TRIANGLES, 0, 3*12); glDisableVertexAttribArray(1); // -> ... in this cast remove these two lines glDisableVertexAttribArray(0); glfwSwapBuffers(window); glfwPollEvents(); } return 0; }