Site Name

Copyright © 2019 All rights reserved | This template is made with ♥ by Gulshan

Example of a triangle with line changing color over time and rectangle filled with texture with OpenGL in C++29

//============================================================================ // Name : GLFWwithCPP.cpp // Author : Gulshan Chaurasia // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //============================================================================ /*following libraries have been included for compiling this * gcc -o "HelloGLFW" ./Main.o -lGLEW -lglfw3 -lGL -lm -ldl -lX11 -lpthread -lXrandr -lXi **/ #include #include // GLEW #define GLEW_STATIC #include // GLFW #include using namespace std; #include #include "Shader.h" void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode); int main() { cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!! glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", nullptr, nullptr); if (window == nullptr) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glewExperimental = GL_TRUE; if (glewInit() != GLEW_OK) { std::cout << "Failed to initialize GLEW" << std::endl; return -1; } glViewport(0, 0, 800, 600); //registering callback, for event handling!! glfwSetKeyCallback(window, key_callback); //INITIALIZING opengl parameters before drawing //triangle coordinates GLfloat vertices[] = { -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f }; //vertex buffer objects (VBO) that can store a large number //of vertices in the GPU’s memory //Just like any object in OpenGL this buffer has a unique ID corresponding to that //buffer, so we can generate one with a buffer ID using the glGenBuffers function: GLuint VBO; glGenBuffers(1, &VBO); //We can bind the newly created buffer to the GL_ARRAY_BUFFER target //with the glBindBuffer function: glBindBuffer(GL_ARRAY_BUFFER, VBO); //From that point on any buffer calls we make (on the GL_ARRAY_BUFFER target) will be used //to configure the currently bound buffer, which is VBO. //Then we can make a call to glBufferData //function that copies the previously defined vertex data into the buffer’s memory: glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); Shader myShader("src/vertexshader.vs","src/fragmentshader.frag"); Shader myShader2("src/vertexshader2.vs","src/fragmentshader2.frag"); //we can tell OpenGL how it should interpret the vertex data (per vertex //attribute) using glVertexAttribPointer: glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); //The process to generate a VAO looks simliar to that of a VBO: GLuint VAO; glGenVertexArrays(1, &VAO); // 1. Bind Vertex Array Object glBindVertexArray(VAO); // 2. Copy our vertices array in a buffer for OpenGL to use //glBindBuffer(GL_ARRAY_BUFFER, VBO);these steps already done above!! //glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // 3. Then set our vertex attributes pointers glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), ( GLvoid*)0); glEnableVertexAttribArray(0); //4. Unbind the VAO glBindVertexArray(0); //INITIALIZING rectangle parameters!! GLfloat vertices2[] = { //Positions //Colors //Texture Coords 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // Top Right 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Bottom Right -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom Left -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f // Top Left }; GLuint indices2[] = { // Note that we start from 0! 0, 1, 3, // First Triangle 1, 2, 3 // Second Triangle }; GLuint VAO2; glGenVertexArrays(1, &VAO2); glBindVertexArray(VAO2); GLuint VBO2; glGenBuffers(1, &VBO2); glBindBuffer(GL_ARRAY_BUFFER, VBO2); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW); GLuint EBO2; glGenBuffers(1, &EBO2); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO2); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices2), indices2, GL_STATIC_DRAW); // Position attribute glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); // Color attribute glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(1); // TexCoord attribute glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat))); glEnableVertexAttribArray(2); // 4. Unbind VAO (NOT the EBO) glBindVertexArray(0); //-----------------------Working with textures------------------------------- glEnable(GL_TEXTURE_2D); //LOADING image from a file using SOIL library , for using as 2D texture int width, height; std::string path = "src/background.png";//if image doesn't load, make sure to check the path is appropriate. //IDEs change the relative path for binaries , even if they are in same folder, its relative path is //different, try using absolute path to image, if it loads image correctly, you know you have problem //with relative path and try to figure it out!! unsigned char* image = SOIL_load_image(path.c_str(), &width, &height, 0, SOIL_LOAD_RGB); std::cout << width << ", " << height << endl; //Like any of the previous objects in OpenGL, textures are referenced with an ID; let’s create one: GLuint texture; glGenTextures(1, &texture); //Just like other objects we need to bind it so any subsequent texture commands will configure the //currently bound texture: glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);//GL_MIRRORED_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);//GL_MIRRORED_REPEAT); //float borderColor[] = { 1.0f, 1.0f, 0.0f, 1.0f }; //glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //Now that the texture is bound, we can start generating a texture using the previously loaded //image data. Textures are generated with glTexImage2D: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); //Once glTexImage2D is called, the currently bound texture object now has the texture image attached to it. glGenerateMipmap(GL_TEXTURE_2D); //After we’re done generating the texture and its corresponding mipmaps, it is good practice to //free the image memory and unbind the texture object: SOIL_free_image_data(image); glBindTexture(GL_TEXTURE_2D, 0); //All that’s left to do now is to bind the texture before calling the glDrawElements and it will //then automatically assign the texture to the fragment shader’s sampler //in the game loop!! //-----------------------#Working with textures------------------------------- //GLint nrAttributes; //glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nrAttributes); //std::cout << "Maximum nr of vertex attributes supported: " << nrAttributes << std::endl; //this is the game loop while(!glfwWindowShouldClose(window)) { glfwPollEvents(); //all the rendering is done here!! glClearColor(0.5f, 0.3f, 0.7f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glBindTexture(GL_TEXTURE_2D, texture); GLint vertexColorLocation = glGetUniformLocation(myShader2.getProgram(), "ourColor"); myShader2.useProgram(); glUniform4f(vertexColorLocation, 1.0f, 1.0f, 1.0f, 0.0f); glBindVertexArray(VAO2); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);//GL_LINE for wireframe, GL_FILL for solid glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glBindVertexArray(0); //The result is a program object that we can activate by calling glUseProgram with the newly //created program object as its argument: //First, we retrieve the running time in seconds via glfwGetTime(). Then we vary the color //in the range of 0.0 - 1.0 by using the sin function and store the result in greenValue. GLfloat timeValue = glfwGetTime(); GLfloat greenValue = (sin(timeValue) / 2) + 0.5; //Then we query for the location of the ourColor uniform using glGetUniformLocation. vertexColorLocation = glGetUniformLocation(myShader.getProgram(), "ourColor"); myShader.useProgram(); glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f); //actual drawing takes place here //Lastly we can set the uniform value using the glUniform4f function. glBindVertexArray(VAO); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//GL_LINE for wireframe, GL_FILL for solid glDrawArrays(GL_TRIANGLES, 0, 3); glBindVertexArray(0); glfwSwapBuffers(window); } glfwTerminate(); return 0; } void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) { // When a user presses the escape key, we set the WindowShouldClose property to true, // closing the application if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE); }

published by gulshan on 2019-12-17 01:03:13

0 likes 0 dislikes