glGenVertexArrays(1, VertexArrayID);
glBindVertexArray(VertexArrayID[0]);
glGenBuffers(2, Buffers);
glBindBuffer(GL_ARRAY_BUFFER, Buffers[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(), vertices.data(),
VertexShader.txt
#version 400 core
in vec3 pos;
void main()
{
gl_Position = vec4 (pos, 1);
gl_PointSize = 10.0f;
}
FragmentShader.txt
#version 400 core
out vec3 color;
void main()
{
color = vec3(1, 0, 0);
}
main.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include <GL/glew.h>
#include <GL/glut.h>
#include <algorithm>
using namespace std;
GLuint VertexArrayID[2]; // VAO
GLuint Buffers[2]; // VBO
vector<float> vertices = {
0.01f, 0.01f, 0.0f,
0.5f, 0.01f, 0.0f,
0.01f, 0.5f, 0.0f,
-0.01f, 0.01f, 0.0f,
-0.5f, 0.01f, 0.0f,
-0.01f, 0.5f, 0.0f,
-0.01f, -0.01f, 0.0f,
-0.5f, -0.01f, 0.0f,
-0.01f, -0.5f, 0.0f,
0.01f, -0.01f, 0.0f,
0.5f, -0.01f, 0.0f,
0.01f, -0.5f, 0.0f
};
vector<float> vertices_point = {};
GLuint LoadShaders(const char* vertex_file_path, const char* fragment_file_path)
{
//create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
GLint Result = GL_FALSE;
int InfoLogLength;
//Read the vertex shader code from the file
string VertexShaderCode;
ifstream VertexShaderStream(vertex_file_path, ios::in);
if (VertexShaderStream.is_open())
{
string Line = "";
while (getline(VertexShaderStream, Line))
VertexShaderCode += "\n" + Line;
VertexShaderStream.close();
}
//Compile Vertex Shader
printf("Compiling shader : %s\n", vertex_file_path);
char const* VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL);
glCompileShader(VertexShaderID);
//Check Vertex Shader
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
vector<char> VertexShaderErrorMessage(InfoLogLength);
if (InfoLogLength != 0) {
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]);
}
//Read the fragment shader code from the file
string FragmentShaderCode;
ifstream FragmentShaderStream(fragment_file_path, ios::in);
if (FragmentShaderStream.is_open())
{
string Line = "";
while (getline(FragmentShaderStream, Line))
FragmentShaderCode += "\n" + Line;
FragmentShaderStream.close();
}
//Compile Fragment Shader
printf("Compiling shader : %s\n", fragment_file_path);
char const* FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL);
glCompileShader(FragmentShaderID);
//Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
vector<char> FragmentShaderErrorMessage(InfoLogLength);
if (InfoLogLength != 0) {
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]);
}
//Link the program
fprintf(stdout, "Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
vector<char> ProgramErrorMessage(max(InfoLogLength, int(1)));
if (InfoLogLength != 0) {
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
fprintf(stdout, "%s\n", &ProgramErrorMessage[0]);
}
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}
void renderScene(void)
{
//Clear all pixels
glClear(GL_COLOR_BUFFER_BIT);
//Let's draw something here
glBindVertexArray(VertexArrayID[0]);
glDrawArrays(GL_TRIANGLES, 0, vertices.size()/3);
glBindVertexArray(VertexArrayID[1]);
glDrawArrays(GL_POINTS, 0, vertices_point.size()/3);
//Double buffer
glutSwapBuffers();
}
void init()
{
//initilize the glew and check the errors.
GLenum res = glewInit();
if (res != GLEW_OK)
{
fprintf(stderr, "Error: '%s' \n", glewGetErrorString(res));
}
//select the background color
glClearColor(1.0, 1.0, 1.0, 1.0);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
}
void myMouseFunc(int btn, int state, int x, int y) {
if (state == GLUT_DOWN && btn == GLUT_LEFT_BUTTON) {
float nx = 2.0f * (float)x / (float)479 - 1.0f; //mapping to world coordinate
float ny = -2.0f * (float)y / (float)479 + 1.0f;
vertices_point.push_back(nx);//vertices
vertices_point.push_back(ny);
vertices_point.push_back(0.0f);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices_point.size(), vertices_point.data(), GL_STATIC_DRAW); // data update
glutPostRedisplay();//re-draw
}
}
int main(int argc, char **argv)
{
//init GLUT and create Window
//initialize the GLUT
glutInit(&argc, argv);
//GLUT_DOUBLE enables double buffering (drawing to a background buffer while the other buffer is displayed)
glutInitDisplayMode(/* GLUT_3_2_CORE_PROFILE | */ GLUT_DOUBLE | GLUT_RGBA);
//These two functions are used to define the position and size of the window.
glutInitWindowPosition(200, 200);
glutInitWindowSize(480, 480);
//This is used to define the name of the window.
glutCreateWindow("Simple OpenGL Window");
//call initization function
init();
//0.
//Generate ID
GLuint programID = LoadShaders("VertexShader.txt", "FragmentShader.txt");
glUseProgram(programID);
//1.
//Generate VAO
glGenVertexArrays(1, VertexArrayID);
//2.
//Generate VBO
glGenBuffers(2, Buffers);
// VAO1
glBindVertexArray(VertexArrayID[0]);
glBindBuffer(GL_ARRAY_BUFFER, Buffers[0]); // for triangles
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(), vertices.data(), GL_STATIC_DRAW);
//link Attribute
GLint posAttrib = glGetAttribLocation(programID, "pos");
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(posAttrib);
// VAO2
glBindVertexArray(VertexArrayID[1]);
glBindBuffer(GL_ARRAY_BUFFER, Buffers[1]); // for points
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices_point.size(), vertices_point.data(), GL_STATIC_DRAW);
//link Attribute
posAttrib = glGetAttribLocation(programID, "pos");
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(posAttrib);
glutDisplayFunc(renderScene);
//Set Function
glutMouseFunc(myMouseFunc);
//enter GLUT event processing cycle
glutMainLoop();
glDeleteVertexArrays(1, VertexArrayID);
return 1;
}