void Particle::init(){ linkShader(); initBuffers(); GLuint gravity = glGetUniformLocation(program, "Gravity"); GLuint plt = glGetUniformLocation(program, "ParticleLifetime"); //GLuint ptex = glGetUniformLocation(program, "ParticleTex"); glUniform1f(plt, 5.0f); //glUniform3f(gravity, 0.0f, -0.2f, 0.0f); angle = half_pi<float>(); projection = mat4(1.0f); model = mat4(1.0f); view = lookAt(vec3(3.0f * cosf(angle), 1.5f, 3.0f * sinf(angle)), vec3(0.0f, 1.5f, 0.0f), vec3(0.0f, 1.0f, 0.0f)); // glUniform1f(gravity, 9.8); mat4 mvpMatrix(1.0f); starttimer = clock(); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); }
void initShader(Vec3 &pos, Mat4 &perspective, Mat4 &cameraTranslation, Mat4 &cameraRotation, PhongMaterial &mat) { BasicShader::initShader(); addVertexShader("../../shaders/light_shadow_v.glsl"); addFragmentShader("../../shaders/light_shadow_f.glsl"); linkShader(); addUniform(std::string("transform")); addUniform(std::string("perspective")); addUniform(std::string("camera")); addUniform(std::string("cameraRotation")); addUniform(std::string("lightMatrix")); addUniform(std::string("specularIntensity")); addUniform(std::string("specularExponent")); addUniform(std::string("eyePos")); addUniform(std::string("dirLight.diffuseIntensity")); addUniform(std::string("dirLight.dir")); addUniform(std::string("dirLight.color")); addUniform(std::string("dirLight.ambientIntensity")); addUniform(std::string("pointLight.color")); addUniform(std::string("pointLight.ambientIntensity")); addUniform(std::string("pointLight.diffuseIntensity")); addUniform(std::string("pointLight.position")); addUniform(std::string("pointLight.att.constant")); addUniform(std::string("pointLight.att.linear")); addUniform(std::string("pointLight.att.exp")); addUniform(std::string("spotLight.color")); addUniform(std::string("spotLight.position")); addUniform(std::string("spotLight.dir")); addUniform(std::string("spotLight.ambientIntensity")); addUniform(std::string("spotLight.diffuseIntensity")); addUniform(std::string("spotLight.cutoff")); addUniform(std::string("spotLight.att.constant")); addUniform(std::string("spotLight.att.linear")); addUniform(std::string("spotLight.att.exp")); addUniform(std::string("sampler")); addUniform(std::string("samplerShadow")); material_ = &mat; perspective_ = &perspective; cameraTranslation_ = &cameraTranslation; cameraRotation_ = &cameraRotation; eyePos_ = pos; }
void Shader::loadShader() { m_ShaderID = glCreateProgram(); GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER); compileShader(m_VertexShaderPath, vertexShaderId); GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER); compileShader(m_FragmentShaderPath, fragmentShaderId); linkShader(m_ShaderID, vertexShaderId, fragmentShaderId); }
GLuint buildShader(const char *vert_src, const char *frag_src, const char *prepend_src) { if (prepend_src) { vert_src = prependShader(vert_src, prepend_src); frag_src = prependShader(frag_src, prepend_src); } GLuint vert_shader = compileShader(GL_VERTEX_SHADER, vert_src); GLuint frag_shader = compileShader(GL_FRAGMENT_SHADER, frag_src); GLuint result = linkShader(vert_shader, frag_shader); glDetachShader(result, vert_shader); glDetachShader(result, frag_shader); glDeleteShader(vert_shader); glDeleteShader(frag_shader); if (prepend_src) { free((char*) vert_src); free((char*) frag_src); } return result; }
GLuint loadShaders( const std::string& vertexFile, const std::string& fragmentFile) { GLuint vertexId = glCreateShader(GL_VERTEX_SHADER); GLuint fragmentId = glCreateShader(GL_FRAGMENT_SHADER); std::string vertexCode = readFile(vertexFile); std::string fragmentCode = readFile(fragmentFile); compileShader(vertexId, vertexCode); compileShader(fragmentId, fragmentCode); GLuint programId = 0; linkShader(vertexId, fragmentId, programId); glDeleteShader(vertexId); glDeleteShader(fragmentId); return programId; }
SpriteBatcher::SpriteBatcher() : camera(NULL), vao(0), program(0), lastTexture(0), drawn(0) { // Create shader program GLuint vertex = createShader(VERTEX_SRC, GL_VERTEX_SHADER); GLuint fragment = createShader(FRAGMENT_SRC, GL_FRAGMENT_SHADER); program = createShaderProgram(vertex, fragment); linkShader(program); validateShader(program); glDetachShader(program, vertex); glDeleteShader(vertex); glDetachShader(program, fragment); glDeleteShader(fragment); // Create vertex array and prepare buffers for being updated >= once per frame glGenVertexArrays(1, &vao); glGenBuffers(2, buffers); glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, buffers[VCTBO]); glBufferData(GL_ARRAY_BUFFER, 0, NULL, GL_DYNAMIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[EBO]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, 0, NULL, GL_DYNAMIC_DRAW); // Attributes glBindBuffer(GL_ARRAY_BUFFER, buffers[VCTBO]); glEnableVertexAttribArray(0); // position glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0); glEnableVertexAttribArray(1); // color glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(2 * sizeof(float))); glEnableVertexAttribArray(2); // texture coordinates glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float))); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); }
void initShader(Vec3 &pos, Mat4 &perspective, Mat4 &cameraTranslation, Mat4 &cameraRotation) { BasicShader::initShader(); addVertexShader("../../shaders/simple_v.glsl"); addFragmentShader("../../shaders/simple_f.glsl"); linkShader(); addUniform(std::string("transform")); addUniform(std::string("perspective")); addUniform(std::string("camera")); addUniform(std::string("cameraRotation")); //addUniform(std::string("model_col")); perspective_ = &perspective; cameraTranslation_ = &cameraTranslation; cameraRotation_ = &cameraRotation; eyePos_ = pos; }
void Shader::createShader(const std::string& shaderFile) { _vertexShaderID = glCreateShader(GL_VERTEX_SHADER); _fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); std::string vertexShaderCode; std::ifstream vertexShaderStream(shaderFile+".vert", std::ios::in); if (vertexShaderStream.is_open()) { std::string line = ""; while (std::getline(vertexShaderStream, line)) vertexShaderCode += "\n" + line; vertexShaderStream.close(); } std::string fragmentShaderCode; std::ifstream fragmentShaderStream(shaderFile + ".frag", std::ios::in); if (fragmentShaderStream.is_open()) { std::string line = ""; while (std::getline(fragmentShaderStream, line)) fragmentShaderCode += "\n" + line; fragmentShaderStream.close(); } compileShader(vertexShaderCode, fragmentShaderCode); checkShaderError(); linkShader(); glDeleteShader(_vertexShaderID); glDeleteShader(_fragmentShaderID); }
void Shader::loadGeometryShader(const std::string &shader) { mGeometryHandle = createSharedObjects(shader, GL_GEOMETRY_SHADER); linkShader(mGeometryHandle); }
/** * @brief Loads a fragment shader * * @param fragmentShader * Fragment program */ void Shader::loadFragmentShader(const std::string &fragmentShader) { mFragmentHandle = createSharedObjects(fragmentShader, GL_FRAGMENT_SHADER); linkShader(mFragmentHandle); }
/** * @brief Loads a vertex shader * * @param vertexPath * Vertex program * */ void Shader::loadVertexShader(const std::string &vertexShader) { mVertexHandle = createSharedObjects(vertexShader, GL_VERTEX_SHADER); linkShader(mVertexHandle); }
int main(void) { GLFWwindow* window; window = init("Transparency", 640, 480); if(!window) { return -1; } glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glm::mat4 proj = glm::perspective(glm::radians(45.0f), (float)640/(float)480, 0.1f, 1000.0f); glm::mat4 model1, model2, model3; // Cube 1 and 2 will be transparent, cube 3 not model1 = glm::translate(model1, glm::vec3(0.5f, 0.0f, -1.0f)); model2 = glm::translate(model2, glm::vec3(0.0f, 0.5f, -2.0f)); model3 = glm::translate(model3, glm::vec3(0.0f, 0.0f, -3.0f)); glm::mat4 view; view = glm::translate(view, glm::vec3(0.0f, 0.0f, -4.0f)); GLuint vertex = createShader(VERTEX_SRC, GL_VERTEX_SHADER); if(!vertex) { return -1; } GLuint fragment = createShader(FRAGMENT_SRC, GL_FRAGMENT_SHADER); if(!fragment) { return -1; } GLuint program = createShaderProgram(vertex, fragment); if(!program) { return -1; } bool result = linkShader(program); if(!result) { return -1; } result = validateShader(program); if(!result) { return -1; } glDetachShader(program, vertex); glDeleteShader(vertex); glDetachShader(program, fragment); glDeleteShader(fragment); glUseProgram(program); GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); GLuint vbo; glGenBuffers(1, &vbo); float vertices[] = { // x y z r g b u v -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f }; glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); // position glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), 0); glEnableVertexAttribArray(1); // color glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(2); // texture coordinates glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(6 * sizeof(GLfloat))); int w, h; GLuint textureTrans = loadImage("transparent.png", &w, &h, 0, true); // GL_TEXTURE0 if(!textureTrans) { return -1; } GLuint textureOpaq = loadImage("opaque.png", &w, &h, 0, true); // GL_TEXTURE0 if(!textureOpaq) { return -1; } glUniform1i(glGetUniformLocation(program, "tex"), 0); // GL_TEXTURE0 GLint viewUL = glGetUniformLocation(program, "view"); glUniformMatrix4fv(viewUL, 1, GL_FALSE, glm::value_ptr(view)); GLint projUL = glGetUniformLocation(program, "projection"); glUniformMatrix4fv(projUL, 1, GL_FALSE, glm::value_ptr(proj)); GLint modelUL = glGetUniformLocation(program, "model"); glClearColor(0.75f, 0.75f, 0.75f, 1.0f); while(!glfwWindowShouldClose(window)) { // Clear (note the addition of GL_DEPTH_BUFFER_BIT) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // We have to sort the objects, rendering the backmost objects first // in this example, model1 is in front of model2, which is in front of model3 // and model3 is the only one using the opaque texture // (This way we can avoid the sorting, making the example a bit easier to follow) glBindTexture(GL_TEXTURE_2D, textureOpaq); glUniformMatrix4fv(modelUL, 1, GL_FALSE, glm::value_ptr(model3)); glDrawArrays(GL_TRIANGLES, 0, 36); glBindTexture(GL_TEXTURE_2D, textureTrans); glUniformMatrix4fv(modelUL, 1, GL_FALSE, glm::value_ptr(model2)); glDrawArrays(GL_TRIANGLES, 0, 36); glUniformMatrix4fv(modelUL, 1, GL_FALSE, glm::value_ptr(model1)); glDrawArrays(GL_TRIANGLES, 0, 36); glfwSwapBuffers(window); glfwPollEvents(); } // Clean up glDeleteBuffers(1, &vbo); glDeleteVertexArrays(1, &vao); glDeleteTextures(1, &textureTrans); glDeleteTextures(1, &textureOpaq); glfwTerminate(); return 0; }
int main(void) { GLFWwindow* window; window = init("Deferred Shading", WIDTH / 2, HEIGHT / 2); if(!window) { return -1; } glEnable(GL_DEPTH_TEST); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); Camera camera(CAMERA_PERSPECTIVE, 45.0f, 0.1f, 1000.0f, (float)WIDTH, (float)HEIGHT); setCamera(&camera); GLuint geomProgram, lightProgram; { // Geometry pass program GLuint vertex = createShader(VERTEX_GEOM_SRC, GL_VERTEX_SHADER); GLuint fragment = createShader(FRAGMENT_GEOM_SRC, GL_FRAGMENT_SHADER); geomProgram = createShaderProgram(vertex, fragment); linkShader(geomProgram); validateShader(geomProgram); glDetachShader(geomProgram, vertex); glDeleteShader(vertex); glDetachShader(geomProgram, fragment); glDeleteShader(fragment); } { // Light pass program GLuint vertex = createShader(VERTEX_LIGHT_SRC, GL_VERTEX_SHADER); GLuint fragment = createShader(FRAGMENT_LIGHT_SRC, GL_FRAGMENT_SHADER); lightProgram = createShaderProgram(vertex, fragment); linkShader(lightProgram); validateShader(lightProgram); glDetachShader(lightProgram, vertex); glDeleteShader(vertex); glDetachShader(lightProgram, fragment); glDeleteShader(fragment); } // Create quad VAO GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); GLuint vbo; glGenBuffers(1, &vbo); float vertices[] = { // x y u v -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 1.0f }; glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); GLuint ebo; glGenBuffers(1, &ebo); GLuint indices[] = { 0, 1, 2, 2, 3, 0 }; glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat))); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // Load the diffuse and specular texture // TODO: seperate specular texture glUseProgram(geomProgram); int w, h; GLuint textureDiff = loadImage("asteroid.png", &w, &h, 0, false); // GL_TEXTURE0 if(!textureDiff) { return -1; } glUniform1i(glGetUniformLocation(geomProgram, "diffuse"), 0); // GL_TEXTURE0 GLuint textureSpec = loadImage("asteroid.png", &w, &h, 1, false); // GL_TEXTURE1 if(!textureSpec) { return -1; } glUniform1i(glGetUniformLocation(geomProgram, "specular"), 1); // GL_TEXTURE1 Mesh mesh; if(!mesh.load("asteroid.obj")) { std::cerr << "Could not load mesh" << std::endl; return -1; } // Set random positions for the asteroids std::vector<glm::mat4> models; models.resize(NUM_ASTEROIDS); srand(SEED); for(int i = 0; i < NUM_ASTEROIDS; ++i) { glm::mat4 model; // Translate model = glm::translate(model, glm::vec3(rand() % 100 - 50.0f, rand() % 100 - 50.0f, rand() % 100)); // Scale float scale = (rand() % 200) / 100.0f + 0.1f; model = glm::scale(model, glm::vec3(scale, scale, scale)); // Rotate model = glm::rotate(model, glm::radians((float)(rand() % 100)), glm::vec3(1.0f, 1.0f, 1.0f)); models[i] = model; } mesh.setInstances(NUM_ASTEROIDS, models); // Set positions and more for the lights PointLight lights[NUM_POINT_LIGHTS]; for(int i = 0; i < NUM_POINT_LIGHTS; ++i) { float x, y, z; x = rand() % 100 - 50.0f; y = rand() % 100 - 50.0f; z = rand() % 100; float r, g, b; // For simplicity's sake, ambient, diffuse and specular colours are the same r = ((rand() % 10) / 20.0f) + 0.5; g = ((rand() % 10) / 20.0f) + 0.5; b = ((rand() % 10) / 20.0f) + 0.5; float con, lin, qua; con = 1.0f; lin = 0.09f; qua = 0.032f; lights[i].set(glm::vec3(x, y, z), glm::vec3(con, lin, qua), glm::vec3(r, g, b), glm::vec3(r, g, b), glm::vec3(r, g, b)); } GBuffer gBuffer; glUseProgram(lightProgram); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, gBuffer.position); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, gBuffer.normal); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, gBuffer.color); glUniform1i(glGetUniformLocation(lightProgram, "g_position"), 0); glUniform1i(glGetUniformLocation(lightProgram, "g_normal_spec_pow"), 1); glUniform1i(glGetUniformLocation(lightProgram, "g_albedo_spec"), 2); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); while(!glfwWindowShouldClose(window)) { if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { break; } updateCamera(WIDTH, HEIGHT, window); // GEOMETRY PASS glBindFramebuffer(GL_FRAMEBUFFER, gBuffer.buffer); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glm::mat4 proj = camera.getProjection(); glm::mat4 view = camera.getView(); glUseProgram(geomProgram); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureDiff); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textureSpec); glUniformMatrix4fv(glGetUniformLocation(geomProgram, "projection"), 1, GL_FALSE, glm::value_ptr(proj)); glUniformMatrix4fv(glGetUniformLocation(geomProgram, "view"), 1, GL_FALSE, glm::value_ptr(view)); glUniform1f(glGetUniformLocation(geomProgram, "specularPower"), 16.0f); mesh.render(); // LIGHT PASS glBindFramebuffer(GL_FRAMEBUFFER, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(lightProgram); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, gBuffer.position); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, gBuffer.normal); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, gBuffer.color); glUniform3fv(glGetUniformLocation(lightProgram, "eye"), 1, glm::value_ptr(camera.getPosition())); for(int i = 0; i < NUM_POINT_LIGHTS; ++i) { lights[i].setUniforms(i, lightProgram); } glBindVertexArray(vao); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glBindVertexArray(0); glfwSwapBuffers(window); glfwPollEvents(); } // Clean up glDeleteTextures(1, &textureDiff); glDeleteTextures(1, &textureSpec); glDeleteProgram(geomProgram); glDeleteProgram(lightProgram); glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &vbo); glDeleteBuffers(1, &ebo); glfwTerminate(); return 0; }
int main(void) { GLFWwindow* window; // The OpenGL context creation code is in // ../common/util.cpp window = init("Hello Heightmap", 640, 480); if(!window) { return -1; } // Hide the cursor (escape will exit the application) glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // We will need to enable depth testing, so that OpenGL draws further // vertices first glEnable(GL_DEPTH_TEST); // Draw wireframe glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // Enable backface culling glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glFrontFace(GL_CCW); // front facing vertices are defined counter clock wise // Create the model matrix model = glm::mat4(); // Rotate just a bit (the vector indicates the axes on which to rotate) model = glm::rotate(model, -glm::radians(35.0f), glm::vec3(0.0f, 1.0f, 1.0f)); // Set the camera Camera camera(CAMERA_PERSPECTIVE, 45.0f, 0.1f, 1000.0f, 640.0f, 480.0f); camera.setPosition(0.0f, 0.0f, -3.0f); setCamera(&camera); // The camera updating is handled in ../common/util.cpp // Load the heightmap HeightMap map(20.0f); if(!map.load("heightmap.bmp")) { return -1; } const std::vector<float>& data = map.getData(); int w = map.getWidth(), h = map.getHeight(); std::vector<float> vertices; for(int i = 0; i < h; ++i) { for(int j = 0; j < w; ++j) { float x = (float)i; float z = (float)j; float height = data[i * w + j]; vertices.push_back(x * SIZE); vertices.push_back(height); vertices.push_back(z * SIZE); // This is where you could add extra information, // like colour or texture coordinates. // You would have to change the vertex attribute pointer // code as well! } } std::vector<GLuint> indices; for(int i = 0; i < (h - 1); ++i) { for(int j = 0; j < (w - 1); ++j) { // We create six indices for each tile indices.push_back(i * w + j); indices.push_back((i + 1) * w + j); indices.push_back(i * w + j + 1); indices.push_back(i * w + j + 1); indices.push_back((i + 1) * w + j); indices.push_back((i + 1) * w + j + 1); } } // We start by creating a vertex and fragment shader // from the above strings GLuint vertex = createShader(VERTEX_SRC, GL_VERTEX_SHADER); if(!vertex) { return -1; } GLuint fragment = createShader(FRAGMENT_SRC, GL_FRAGMENT_SHADER); if(!fragment) { return -1; } // Now we must make a shader program: this program // contains both the vertex and the fragment shader GLuint program = createShaderProgram(vertex, fragment); if(!program) { return -1; } // We link the program, just like your C compiler links // .o files bool result = linkShader(program); if(!result) { return -1; } // We make sure the shader is validated result = validateShader(program); if(!result) { return -1; } // Detach and delete the shaders, because we no longer need them glDetachShader(program, vertex); glDeleteShader(vertex); glDetachShader(program, fragment); glDeleteShader(fragment); glUseProgram(program); // Set this as the current shader program // We now create the data to send to the GPU GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); GLuint vbo; glGenBuffers(1, &vbo); // Upload the vertices to the buffer glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(), &vertices[0], GL_STATIC_DRAW); GLuint ebo; glGenBuffers(1, &ebo); // Upload the indices to the buffer glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indices.size(), &indices[0], GL_STATIC_DRAW); // Enable the vertex attributes and upload their data (see: layout(location=x)) glEnableVertexAttribArray(0); // position glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0); // We have now successfully created a drawable Vertex Array Object // Set the clear color to a light grey glClearColor(0.75f, 0.75f, 0.75f, 1.0f); while(!glfwWindowShouldClose(window)) { if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { break; } updateCamera(640, 480, window); // Clear (note the addition of GL_DEPTH_BUFFER_BIT) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Upload the MVP matrices GLint modelUL = glGetUniformLocation(program, "model"); glUniformMatrix4fv(modelUL, 1, GL_FALSE, glm::value_ptr(model)); GLint viewUL = glGetUniformLocation(program, "view"); glUniformMatrix4fv(viewUL, 1, GL_FALSE, glm::value_ptr(camera.getView())); // This can be moved out of the loop because it rarely changes GLint projUL = glGetUniformLocation(program, "projection"); glUniformMatrix4fv(projUL, 1, GL_FALSE, glm::value_ptr(camera.getProjection())); // The VAO is still bound so just draw the vertices glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0); // Tip: if nothing is drawn, check the return value of glGetError and google it // Swap buffers to show current image on screen (for more information google 'backbuffer') glfwSwapBuffers(window); glfwPollEvents(); } // Clean up glDeleteBuffers(1, &vbo); glDeleteBuffers(1, &ebo); glDeleteVertexArrays(1, &vao); glfwTerminate(); return 0; }
int main(void) { GLFWwindow* window = init("Morph Target Animation", 640, 480); if(!window) { return -1; } glEnable(GL_DEPTH_TEST); glm::mat4 proj = glm::perspective(glm::radians(45.0f), 640.0f / 480.0f, 0.1f, 1000.0f); glm::mat4 view = glm::translate(glm::mat4(), glm::vec3(0.0f, 0.0f, -4.0f)); glm::mat4 model = glm::rotate(glm::mat4(), glm::radians(45.0f), glm::vec3(1.0f, 0.0f, 1.0f)); // Load the shader GLuint program; { GLuint vertex = createShader(VERTEX_SRC, GL_VERTEX_SHADER); GLuint fragment = createShader(FRAGMENT_SRC, GL_FRAGMENT_SHADER); program = createShaderProgram(vertex, fragment); linkShader(program); validateShader(program); glDetachShader(program, vertex); glDeleteShader(vertex); glDetachShader(program, fragment); glDeleteShader(fragment); if(!program) { return -1; } } glUseProgram(program); float vertices1[] = { // x y z -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, }; float vertices2[] = { // x y z -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, }; // Create the vao and buffer objects GLuint vao; GLuint buffers[2]; glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(2, buffers); glBindBuffer(GL_ARRAY_BUFFER, buffers[CUR_POS_VBO]); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), vertices1, GL_DYNAMIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); glBindBuffer(GL_ARRAY_BUFFER, buffers[NEXT_POS_VBO]); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_DYNAMIC_DRAW); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glUniformMatrix4fv(glGetUniformLocation(program, "projection"), 1, GL_FALSE, glm::value_ptr(proj)); glUniformMatrix4fv(glGetUniformLocation(program, "view"), 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(glGetUniformLocation(program, "model"), 1, GL_FALSE, glm::value_ptr(model)); glClearColor(0.75f, 0.75f, 0.75f, 1.0f); float timeSinceFrame = 0.0f; int currentFrame; glBindVertexArray(vao); while(!glfwWindowShouldClose(window)) { // If the time for a frame has passed, we have to switch frames timeSinceFrame += glfwGetTime(); if(timeSinceFrame >= FRAME_TIME) { if(currentFrame == 0) { currentFrame = 1; } else { currentFrame = 0; } timeSinceFrame = 0.0f; // Update the buffers glBindBuffer(GL_ARRAY_BUFFER, buffers[CUR_POS_VBO]); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), currentFrame == 0 ? vertices1 : vertices2, GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, buffers[NEXT_POS_VBO]); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), currentFrame == 0 ? vertices2 : vertices1, GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUniform1f(glGetUniformLocation(program, "tween"), timeSinceFrame / FRAME_TIME); glDrawArrays(GL_TRIANGLES, 0, 36); glfwSetTime(0.0); glfwSwapBuffers(window); glfwPollEvents(); } glDeleteBuffers(2, buffers); glDeleteVertexArrays(1, &vao); glDeleteProgram(program); glfwTerminate(); return 0; }
int main(void) { GLFWwindow* window; window = init("Billboards", 640, 480); if(!window) { return -1; } glEnable(GL_DEPTH_TEST); Camera camera(CAMERA_PERSPECTIVE, 45.0f, 0.1f, 1000.0f, 640.0f, 480.0f); camera.setPosition(0.0f, 0.0f, -3.0f); setCamera(&camera); // The camera updating is handled in ../common/util.cpp glm::mat4 model; GLuint program; { GLuint vertex = createShader(VERTEX_SRC, GL_VERTEX_SHADER); GLuint fragment = createShader(FRAGMENT_SRC, GL_FRAGMENT_SHADER); program = createShaderProgram(vertex, fragment); linkShader(program); validateShader(program); glDetachShader(program, vertex); glDeleteShader(vertex); glDetachShader(program, fragment); glDeleteShader(fragment); } GLuint billboardProgram; { GLuint vertex = createShader(VERTEX_BB_SRC, GL_VERTEX_SHADER); GLuint fragment = createShader(FRAGMENT_BB_SRC, GL_FRAGMENT_SHADER); billboardProgram = createShaderProgram(vertex, fragment); linkShader(billboardProgram); validateShader(billboardProgram); glDetachShader(program, vertex); glDeleteShader(vertex); glDetachShader(program, fragment); glDeleteShader(fragment); } glUseProgram(program); GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); GLuint vbo; glGenBuffers(1, &vbo); float vertices[] = { // x y z r g b u v -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f }; glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); // position glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), 0); glEnableVertexAttribArray(1); // color glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(2); // texture coordinates glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(6 * sizeof(GLfloat))); float verts_bb[] = { -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f }; GLuint vbo_bb; glGenBuffers(1, &vbo_bb); GLuint vao_bb; glGenVertexArrays(1, &vao_bb); glBindVertexArray(vao_bb); glBindBuffer(GL_ARRAY_BUFFER, vbo_bb); glBufferData(GL_ARRAY_BUFFER, sizeof(verts_bb), verts_bb, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); glUseProgram(billboardProgram); glUniform3f(glGetUniformLocation(billboardProgram, "center"), 0.0f, 2.0f, 0.0f); glUniform2f(glGetUniformLocation(billboardProgram, "size"), 0.5f, 0.5f); int w, h; GLuint texture = loadImage("image.png", &w, &h, 0, false); glUniform1i(glGetUniformLocation(billboardProgram, "tex"), 0); glUseProgram(program); glUniform1i(glGetUniformLocation(program, "tex"), 0); glClearColor(0.75f, 0.75f, 0.75f, 1.0f); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); while(!glfwWindowShouldClose(window)) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); updateCamera(640, 480, window); // Draw the cube glUseProgram(program); glBindVertexArray(vao); GLint modelUL = glGetUniformLocation(program, "model"); glUniformMatrix4fv(modelUL, 1, GL_FALSE, glm::value_ptr(model)); GLint viewUL = glGetUniformLocation(program, "view"); glUniformMatrix4fv(viewUL, 1, GL_FALSE, glm::value_ptr(camera.getView())); GLint projUL = glGetUniformLocation(program, "projection"); glUniformMatrix4fv(projUL, 1, GL_FALSE, glm::value_ptr(camera.getProjection())); glDrawArrays(GL_TRIANGLES, 0, 36); // Draw the billboard glBindVertexArray(vao_bb); glUseProgram(billboardProgram); viewUL = glGetUniformLocation(billboardProgram, "view"); glUniformMatrix4fv(viewUL, 1, GL_FALSE, glm::value_ptr(camera.getView())); projUL = glGetUniformLocation(billboardProgram, "proj"); glUniformMatrix4fv(projUL, 1, GL_FALSE, glm::value_ptr(camera.getProjection())); glUniform1i(glGetUniformLocation(billboardProgram, "fixedSize"), 0); glUniform3f(glGetUniformLocation(billboardProgram, "camRight"), camera.getRightVector().x, camera.getRightVector().y, camera.getRightVector().z); glUniform3f(glGetUniformLocation(billboardProgram, "camUp"), camera.getUpVector().x, camera.getUpVector().y, camera.getUpVector().z); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glfwSwapBuffers(window); glfwPollEvents(); } // Clean up glDeleteBuffers(1, &vbo); glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &vbo_bb); glDeleteVertexArrays(1, &vao_bb); glDeleteProgram(program); glDeleteProgram(billboardProgram); glDeleteTextures(1, &texture); glfwTerminate(); return 0; }