void Shader::init(const char *_vsFile, const char *_fsFile) { shader_vp = glCreateShader(GL_VERTEX_SHADER); shader_fp = glCreateShader(GL_FRAGMENT_SHADER); const char *vsText = textFileRead(_vsFile); const char *fsText = textFileRead(_fsFile); if (vsText == nullptr || fsText == nullptr) { std::cout << "ERROR: Either vertex or fragment shader file could not be found" << std::endl; return; } glShaderSource(shader_vp, 1, &vsText, 0); glShaderSource(shader_fp, 1, &fsText, 0); glCompileShader(shader_vp); validateShader(shader_vp, _vsFile); glCompileShader(shader_fp); validateShader(shader_fp, _fsFile); shader_id = glCreateProgram(); glAttachShader(shader_id, shader_fp); glAttachShader(shader_id, shader_vp); glLinkProgram(shader_id); validateProgram(shader_id); delete vsText; delete fsText; }
void Shader::compile() { // compile the shader and attempt to vlidate it glCompileShader(m_shaderHandle); if (!validateShader(m_shaderHandle, m_shaderFile.c_str())) { return; } m_compiled = true; }
unsigned Shader::loadShader(const char *fileName, GLenum shaderType){ unsigned shader_id = 0; FILE* file; long file_size = -1; const char* glsl_source; glsl_source = textFileRead(fileName); shader_id = glCreateShader(shaderType); glShaderSource(shader_id, 1, &glsl_source, 0); glCompileShader(shader_id); validateShader(shader_id); return shader_id; }
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); }
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; }
bool Shader::initInContext(unsigned int contextId) { // handler for the single shaders GLuint vs = 0; GLuint fs = 0; GLuint gs = 0; // return values for the compile process GLint vsCompiled = 0; GLint fsCompiled = 0; GLint gsCompiled = 0; // iterator for program parameter std::map<GLenum,int>::iterator params; #ifndef GLOOST_SYSTEM_DISABLE_OUTPUT_MESSAGES std::cerr << std::endl; std::cerr << std::endl << "Message from Message from Shader::initInContext() on SharedResource " << getSharedResourceId() << ":"; std::cerr << std::endl << " Building for context " << contextId << "."; std::cerr << std::endl; #endif // remove this resource if it allready exists removeFromContext(contextId); /// create a vertex, a fragment and a geometry shader handle vs = glCreateShader( GL_VERTEX_SHADER ); fs = glCreateShader( GL_FRAGMENT_SHADER ); if (_geometryShaderSource) { gs = glCreateShader( GL_GEOMETRY_SHADER ); } /// send shader source to the driver glShaderSource(vs, 1, &_vertexShaderSource, NULL); glShaderSource(fs, 1, &_fragmentShaderSource, NULL); if (_geometryShaderSource) { glShaderSource(gs, 1, &_geometryShaderSource, NULL); } // vertex shader glCompileShader(vs); glGetShaderiv(vs, GL_COMPILE_STATUS, &vsCompiled); if (vsCompiled == GL_FALSE) { #ifndef GLOOST_SYSTEM_DISABLE_OUTPUT_ERRORS std::cerr << std::endl; std::cerr << std::endl << "ERROR in shader::create() on SharedResource " << getSharedResourceId() << ":"; std::cerr << std::endl << " Can't compile vertexshader \"" << _vertexShaderFileName << "\""; std::cerr << std::endl; #endif } // validate the vertex shader and print compiler log validateShader(vs, _vertexShaderFileName); // fragment shader glCompileShader( fs ); glGetShaderiv(fs, GL_COMPILE_STATUS, &fsCompiled); if (fsCompiled == GL_FALSE) { #ifndef GLOOST_SYSTEM_DISABLE_OUTPUT_ERRORS std::cerr << std::endl; std::cerr << std::endl << "ERROR in shader::create() on SharedResource " << getSharedResourceId() << ":"; std::cerr << std::endl << " Cant't compile fragmentshader \"" << _fragmentShaderFileName << "\""; std::cerr << std::endl; #endif } // validate the fragment shader and print compiler log validateShader(fs, _fragmentShaderFileName); // geometry shader if (gs) { glCompileShader( gs ); glGetShaderiv(gs, GL_COMPILE_STATUS, &gsCompiled); if (gsCompiled == GL_FALSE) { #ifndef GLOOST_SYSTEM_DISABLE_OUTPUT_ERRORS std::cerr << std::endl; std::cerr << std::endl << "ERROR in shader::create() on SharedResource " << getSharedResourceId() << ":"; std::cerr << std::endl << " Cant't compile geometryshader \"" << _geometryShaderFileName << "\""; std::cerr << std::endl; #endif } // validate the fragment shader and print compiler log validateShader(gs, _geometryShaderFileName); } else { // shader not used - set compile flag anyway gsCompiled = GL_TRUE; }// if (geometry shader exist) /// create a shader program and attache the compiled vertex, fragment and geometry binaries unsigned int shaderHandle = glCreateProgram(); /// make a association between the context and the GL handle of this shader setResourceHandleForContext(shaderHandle, contextId); /// attache programs to shaderh handle glAttachShader( shaderHandle, fs ); glAttachShader( shaderHandle, vs ); if (gs) { glAttachShader( shaderHandle, gs ); CheckErrorsGL(("Shader::initInContext() after attaching geometry shader for Shared Resource " + gloost::toString(getSharedResourceId())).c_str()); for ( params =_programParameter.begin(); params != _programParameter.end(); params++ ) { glProgramParameteriEXT(shaderHandle, (*params).first, (*params).second); CheckErrorsGL(("Shader::initInContext() after setting for Shared Resource " + gloost::toString(getSharedResourceId())).c_str()); } } /// link programs glLinkProgram(shaderHandle); // int temp; // glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT,&temp); // std::cerr << std::endl << "GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT: " << temp; #ifndef GLOOST_SYSTEM_DISABLE_OUTPUT_MESSAGES if (vsCompiled == GL_TRUE && fsCompiled == GL_TRUE && gsCompiled == GL_TRUE) { std::cerr << std::endl; std::cerr << std::endl << "Message from Shader::compileToProgram() on SharedResource " << getSharedResourceId() << ":"; std::cerr << std::endl << " Successfully compiled and linked."; std::cerr << std::endl << " \"" << _vertexShaderFileName << "\", "; std::cerr << std::endl << " \"" << _fragmentShaderFileName << "\""; if (gs) { std::cerr << ", "<< std::endl << " \"" << _geometryShaderFileName << "\""; } std::cerr << std::endl; return true; } #endif return false; }
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; }