Created
November 26, 2014 06:08
-
-
Save tomdalling/702a1706ef4a853b29c6 to your computer and use it in GitHub Desktop.
tomdalling.com OpenGL article 2 modified to use two textures
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 150 | |
uniform sampler2D tex; | |
uniform sampler2D tex2; | |
in vec2 fragTexCoord; | |
out vec4 finalColor; | |
void main() { | |
vec4 color1 = texture(tex, fragTexCoord); | |
vec4 color2 = texture(tex2, fragTexCoord); | |
finalColor = 0.5*color1 + 0.5*color2; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
main | |
Copyright 2012 Thomas Dalling - http://tomdalling.com/ | |
Licensed under the Apache License, Version 2.0 (the "License"); | |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, software | |
distributed under the License is distributed on an "AS IS" BASIS, | |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
See the License for the specific language governing permissions and | |
limitations under the License. | |
*/ | |
#include "platform.hpp" | |
// third-party libraries | |
#include <GL/glew.h> | |
#include <GLFW/glfw3.h> | |
#include <glm/glm.hpp> | |
// standard C++ libraries | |
#include <cassert> | |
#include <iostream> | |
#include <stdexcept> | |
#include <cmath> | |
// tdogl classes | |
#include "tdogl/Program.h" | |
#include "tdogl/Texture.h" | |
// constants | |
const glm::vec2 SCREEN_SIZE(800, 600); | |
// globals | |
GLFWwindow* gWindow = NULL; | |
tdogl::Texture* gTexture = NULL; | |
tdogl::Texture* gTexture2 = NULL; | |
tdogl::Program* gProgram = NULL; | |
GLuint gVAO = 0; | |
GLuint gVBO = 0; | |
// loads the vertex shader and fragment shader, and links them to make the global gProgram | |
static void LoadShaders() { | |
std::vector<tdogl::Shader> shaders; | |
shaders.push_back(tdogl::Shader::shaderFromFile(ResourcePath("vertex-shader.txt"), GL_VERTEX_SHADER)); | |
shaders.push_back(tdogl::Shader::shaderFromFile(ResourcePath("fragment-shader.txt"), GL_FRAGMENT_SHADER)); | |
gProgram = new tdogl::Program(shaders); | |
} | |
// loads a triangle into the VAO global | |
static void LoadTriangle() { | |
// make and bind the VAO | |
glGenVertexArrays(1, &gVAO); | |
glBindVertexArray(gVAO); | |
// make and bind the VBO | |
glGenBuffers(1, &gVBO); | |
glBindBuffer(GL_ARRAY_BUFFER, gVBO); | |
// Put the three triangle vertices (XYZ) and texture coordinates (UV) into the VBO | |
GLfloat vertexData[] = { | |
// X Y Z U V | |
0.0f, 0.8f, 0.0f, 0.5f, 1.0f, | |
-0.8f,-0.8f, 0.0f, 0.0f, 0.0f, | |
0.8f,-0.8f, 0.0f, 1.0f, 0.0f, | |
}; | |
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW); | |
// connect the xyz to the "vert" attribute of the vertex shader | |
glEnableVertexAttribArray(gProgram->attrib("vert")); | |
glVertexAttribPointer(gProgram->attrib("vert"), 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), NULL); | |
// connect the uv coords to the "vertTexCoord" attribute of the vertex shader | |
glEnableVertexAttribArray(gProgram->attrib("vertTexCoord")); | |
glVertexAttribPointer(gProgram->attrib("vertTexCoord"), 2, GL_FLOAT, GL_TRUE, 5*sizeof(GLfloat), (const GLvoid*)(3 * sizeof(GLfloat))); | |
// unbind the VAO | |
glBindVertexArray(0); | |
} | |
// loads the file "hazard.png" into gTexture | |
static void LoadTexture() { | |
tdogl::Bitmap bmp = tdogl::Bitmap::bitmapFromFile(ResourcePath("hazard.png")); | |
bmp.flipVertically(); | |
gTexture = new tdogl::Texture(bmp); | |
tdogl::Bitmap bmp2 = tdogl::Bitmap::bitmapFromFile(ResourcePath("hazard2.png")); | |
bmp2.flipVertically(); | |
gTexture2 = new tdogl::Texture(bmp2); | |
} | |
// draws a single frame | |
static void Render() { | |
// clear everything | |
glClearColor(0, 0, 0, 1); // black | |
glClear(GL_COLOR_BUFFER_BIT); | |
// bind the program (the shaders) | |
gProgram->use(); | |
// bind the texture and set the "tex" uniform in the fragment shader | |
glActiveTexture(GL_TEXTURE0); | |
glBindTexture(GL_TEXTURE_2D, gTexture->object()); | |
gProgram->setUniform("tex", 0); //set to 0 because the texture is bound to GL_TEXTURE0 | |
glActiveTexture(GL_TEXTURE1); | |
glBindTexture(GL_TEXTURE_2D, gTexture2->object()); | |
gProgram->setUniform("tex2", 1); //set to 0 because the texture is bound to GL_TEXTURE0 | |
// bind the VAO (the triangle) | |
glBindVertexArray(gVAO); | |
// draw the VAO | |
glDrawArrays(GL_TRIANGLES, 0, 3); | |
// unbind the VAO, the program and the texture | |
glBindVertexArray(0); | |
glBindTexture(GL_TEXTURE_2D, 0); | |
gProgram->stopUsing(); | |
// swap the display buffers (displays what was just drawn) | |
glfwSwapBuffers(gWindow); | |
} | |
void OnError(int errorCode, const char* msg) { | |
throw std::runtime_error(msg); | |
} | |
// the program starts here | |
void AppMain() { | |
// initialise GLFW | |
glfwSetErrorCallback(OnError); | |
if(!glfwInit()) | |
throw std::runtime_error("glfwInit failed"); | |
// open a window with GLFW | |
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); | |
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); | |
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); | |
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); | |
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); | |
gWindow = glfwCreateWindow((int)SCREEN_SIZE.x, (int)SCREEN_SIZE.y, "OpenGL Tutorial", NULL, NULL); | |
if(!gWindow) | |
throw std::runtime_error("glfwCreateWindow failed. Can your hardware handle OpenGL 3.2?"); | |
// GLFW settings | |
glfwMakeContextCurrent(gWindow); | |
// initialise GLEW | |
glewExperimental = GL_TRUE; //stops glew crashing on OSX :-/ | |
if(glewInit() != GLEW_OK) | |
throw std::runtime_error("glewInit failed"); | |
// print out some info about the graphics drivers | |
std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl; | |
std::cout << "GLSL version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl; | |
std::cout << "Vendor: " << glGetString(GL_VENDOR) << std::endl; | |
std::cout << "Renderer: " << glGetString(GL_RENDERER) << std::endl; | |
// make sure OpenGL version 3.2 API is available | |
if(!GLEW_VERSION_3_2) | |
throw std::runtime_error("OpenGL 3.2 API is not available."); | |
// OpenGL settings | |
glEnable(GL_BLEND); | |
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
// load vertex and fragment shaders into opengl | |
LoadShaders(); | |
// load the texture | |
LoadTexture(); | |
// create buffer and fill it with the points of the triangle | |
LoadTriangle(); | |
// run while the window is open | |
while(!glfwWindowShouldClose(gWindow)){ | |
// process pending events | |
glfwPollEvents(); | |
// draw one frame | |
Render(); | |
} | |
// clean up and exit | |
glfwTerminate(); | |
} | |
int main(int argc, char *argv[]) { | |
try { | |
AppMain(); | |
} catch (const std::exception& e){ | |
std::cerr << "ERROR: " << e.what() << std::endl; | |
return EXIT_FAILURE; | |
} | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment