开发环境:
MAC、xcode
上代码:
1.main.cpp
#include <iostream>
#include "Argument.h"
#include "Function.h"
using namespace std;
int main()
{
initGL();
GLFWwindow *window = glfwCreateWindow(800, 600, "LEARN OPENGL!", nullptr, nullptr);
if (window == nullptr)
{
cout << "Failed to create GLFW window" << endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
std::cout << "Failed to initialize GLEW" << std::endl;
return -1;
}
int width,height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
initShader();
drawTwoSameTriangles();
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBindVertexArray(VAOs[0]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glUseProgram(shaderProgramYellow);
glBindVertexArray(VAOs[1]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glfwSwapBuffers(window);
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
glfwTerminate();
return 0;
}
void initGL()
{
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);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
void initShader()
{
GLuint vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader,1,&vertexShaderSource,NULL);
glCompileShader(vertexShader);
compileVertex(vertexShader);
GLuint fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader,1,&fragmentShaderSource,NULL);
glCompileShader(fragmentShader);
compileVertex(fragmentShader);
GLuint fragmentShaderYellow;
fragmentShaderYellow = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShaderYellow,1,&fragmentShader2Source,NULL);
glCompileShader(fragmentShaderYellow);
compileVertex(fragmentShaderYellow);
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram,vertexShader);
glAttachShader(shaderProgram,fragmentShader);
glLinkProgram(shaderProgram);
detectShaderLink(shaderProgram);
shaderProgramYellow = glCreateProgram();
glAttachShader(shaderProgramYellow,vertexShader);
glAttachShader(shaderProgramYellow,fragmentShaderYellow);
glLinkProgram(shaderProgramYellow);
detectShaderLink(shaderProgramYellow);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glDeleteShader(fragmentShaderYellow);
}
void compileVertex(GLuint vertex)
{
GLint sucess;
GLchar infoLog[512];
glGetShaderiv(vertex,GL_COMPILE_STATUS,&sucess);
if (!sucess)
{
glGetShaderInfoLog(vertex, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
}
void detectShaderLink(GLuint shaderProgram)
{
GLint success;
GLchar infoLog[512];
glGetProgramiv(shaderProgram,GL_LINK_STATUS,&success);
if (!success)
{
glGetShaderInfoLog(shaderProgram,512,NULL,infoLog);
}
}
void renderTriangle()
{
GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void ElementBufferTest()
{
GLfloat vertices[] = {
0.5f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
-0.5f, 0.5f, 0.0f
};
GLuint indices[] = {
0,1,3,
1,2,3
};
glGenVertexArrays(1,&VAO);
glGenBuffers(1,&VBO);
glGenBuffers(1,&EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER,VBO);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_STATIC_DRAW);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3*sizeof(GLfloat),(GLvoid*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArray(0);
}
void drawTwoTriangles()
{
GLfloat vertices[] = {
-0.9f, -0.5f, 0.0f,
-0.0f, -0.5f, 0.0f,
-0.45f, 0.5f, 0.0f,
0.0f, -0.5f, 0.0f,
0.9f, -0.5f, 0.0f,
0.45f, 0.5f, 0.0f
};
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void drawTwoSameTriangles()
{
GLfloat vertices1[] = {
-0.9f, -0.5f, 0.0f,
-0.0f, -0.5f, 0.0f,
-0.45f, 0.5f, 0.0f,
};
GLfloat vertices2[] = {
0.0f, -0.5f, 0.0f,
0.9f, -0.5f, 0.0f,
0.45f, 0.5f, 0.0f
};
glGenVertexArrays(NUM,VAOs);
glGenBuffers(NUM,VBOs);
glBindVertexArray(VAOs[0]);
glBindBuffer(GL_ARRAY_BUFFER,VBOs[0]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices1),vertices1,GL_STATIC_DRAW);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3*sizeof(GLfloat),(GLvoid*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
glBindVertexArray(VAOs[1]);
glBindBuffer(GL_ARRAY_BUFFER,VBOs[1]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices2),vertices2,GL_STATIC_DRAW);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3*sizeof(GLfloat),(GLvoid*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
}
2.Function.h
#ifndef Function_h
#define Function_h
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include "Argument.h"
using namespace std;
void initGL();
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
void compileVertex(GLuint vertex);
void detectShaderLink(GLuint shaderProgram);
void initShader();
void renderTriangle();
void ElementBufferTest();
void drawTwoTriangles();
void drawTwoSameTriangles();
#endif /* Function_h */
3. Argument.h
#ifndef Argument_h
#define Argument_h
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#define NUM 2
const GLchar* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(position.x, position.y, position.z, 1.0);\n"
"}\0";
const GLchar* fragmentShaderSource = "#version 330 core\n"
"out vec4 color;\n"
"void main()\n"
"{\n"
"color = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";
const GLchar* fragmentShader2Source = "#version 330 core\n"
"out vec4 color;\n"
"void main()\n"
"{\n"
"color = vec4(0.0f, 1.0f, 0.0f, 1.0f); // The color yellow \n"
"}\n\0";
GLuint VBO, VAO, EBO;
GLuint VBOs[NUM],VAOs[NUM],EBOs[NUM];
GLuint shaderProgram;
GLuint shaderProgramYellow;
#endif /* Argument_h */