1. 程式人生 > >OpenGL學習之繪製三角形

OpenGL學習之繪製三角形

開發環境:

MAC、xcode

上程式碼:

1.main.cpp

//
//  main.cpp
//  GL_example
//
//  Created by LiYong on 2018/2/28.
//

#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(); //1.繪製一個三角形 // renderTriangle(); //2.繪製兩個三角形組成一個矩形 // ElementBufferTest();
//3.繪製兩個三角形 // drawTwoTriangles(); //4.使用不同的VAO、VBO繪製兩個三角形 drawTwoSameTriangles(); while (!glfwWindowShouldClose(window)) { glfwPollEvents(); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(shaderProgram); // glBindVertexArray(VAO); // glDrawArrays(GL_TRIANGLES, 0, 6); // glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); 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); //Mac環境下必須新增這一行 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); } void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) { // 當用戶按下ESC鍵,我們設定window視窗的WindowShouldClose屬性為true // 關閉應用程式 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, // Left -0.0f, -0.5f, 0.0f, // Right -0.45f, 0.5f, 0.0f, // Top 0.0f, -0.5f, 0.0f, // Left 0.9f, -0.5f, 0.0f, // Right 0.45f, 0.5f, 0.0f // Top }; 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, // Left -0.0f, -0.5f, 0.0f, // Right -0.45f, 0.5f, 0.0f, // Top }; GLfloat vertices2[] = { 0.0f, -0.5f, 0.0f, // Left 0.9f, -0.5f, 0.0f, // Right 0.45f, 0.5f, 0.0f // Top }; 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

//
//  Function.h
//  GL_example
//
//  Created by LiYong on 2018/3/9.
//

#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

//
//  Argument.h
//  GL_example
//
//  Created by LiYong on 2018/3/9.
//

#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 */