配置OpenGL环境看第一篇文章
此代码为老师给的样例代码基础上进行修改
工程文件
按up和down进行缩放:
按left和right进行旋转:
首先全局定义要用到的一些变量:
float x_delta = 0.1f; //每次移动距离
float x_press_num = 0; //x偏移
float y_press_num = 0; //y偏移
glm::vec3 size = glm::vec3(1.0f); //物体大小
float angle = 0.0f; //旋转角度
创建和绑定好三角形的顶点和颜色信息:
在这里插入代码片
```cpp
const GLfloat triangle[] =
{
-0.5f, -0.5f, +0.0f, // left
+1.0f, +0.0f, +0.0f, // color
+0.5f, -0.5f, +0.0f, // right
+1.0f, +0.0f, +0.0f,
+0.0f, +0.5f, +0.0f, // top
+1.0f, +0.0f, +0.0f,
};
GLuint vaoID;
glGenVertexArrays(1, &vaoID);
glBindVertexArray(vaoID); //first VAO
GLuint vboID;
glGenBuffers(1, &vboID);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangle), triangle, GL_STATIC_DRAW);
// vertex position
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), 0);
// vertex color
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (char*)(3 * sizeof(float)));
每次渲染初始化模型矩阵,对其进行响应的变化然后传到着色器中,最后画出三角形
glm::mat4 model = glm::mat4(1.0f);
model = glm::rotate(model, angle, glm::vec3(0.0f, 0.0f, 1.0f));
model = glm::translate(model, glm::vec3(x_delta * x_press_num, x_delta * y_press_num, 0.0f));
model = glm::scale(model, glm::vec3(size));
glUniformMatrix4fv(glGetUniformLocation(programID, "model"), 1, GL_FALSE, &model[0][0]);
glDrawArrays(GL_TRIANGLES, 0, 6); //render primitives from array data
定义按键事件:
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
if (key == GLFW_KEY_A && action == GLFW_PRESS) {
x_press_num -= 1;
}
if (key == GLFW_KEY_D && action == GLFW_PRESS) {
x_press_num += 1;
}
if (key == GLFW_KEY_W && action == GLFW_PRESS) {
y_press_num += 1;
}
if (key == GLFW_KEY_S && action == GLFW_PRESS) {
y_press_num -= 1;
}
if (key == GLFW_KEY_UP && action == GLFW_PRESS) {
size += glm::vec3(0.1f);
}
if (key == GLFW_KEY_DOWN && action == GLFW_PRESS) {
size -= glm::vec3(0.1f);
}
if (key == GLFW_KEY_LEFT && action == GLFW_PRESS) {
angle += 1.0f;
}
if (key == GLFW_KEY_RIGHT && action == GLFW_PRESS) {
angle -= 1.0f;
}
}
完整main.cpp
#include "Dependencies/glew/glew.h"
#include "Dependencies/GLFW/glfw3.h"
#include "Dependencies/glm/glm.hpp"
#include "Dependencies/glm/gtc/matrix_transform.hpp"
#include
#include
GLuint programID;
float x_delta = 0.1f; //每次移动距离
float x_press_num = 0; //x偏移
float y_press_num = 0; //y偏移
glm::vec3 size = glm::vec3(1.0f); //物体大小
float angle = 0.0f; //旋转角度
void get_OpenGL_info() {
// OpenGL information
const GLubyte* name = glGetString(GL_VENDOR);
const GLubyte* renderer = glGetString(GL_RENDERER);
const GLubyte* glversion = glGetString(GL_VERSION);
std::cout << "OpenGL company: " << name << std::endl;
std::cout << "Renderer name: " << renderer << std::endl;
std::cout << "OpenGL version: " << glversion << std::endl;
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
glViewport(0, 0, width, height);
}
void sendDataToOpenGL() {
const GLfloat triangle[] =
{
-0.5f, -0.5f, +0.0f, // left
+1.0f, +0.0f, +0.0f, // color
+0.5f, -0.5f, +0.0f, // right
+1.0f, +0.0f, +0.0f,
+0.0f, +0.5f, +0.0f, // top
+1.0f, +0.0f, +0.0f,
};
GLuint vaoID;
glGenVertexArrays(1, &vaoID);
glBindVertexArray(vaoID); //first VAO
GLuint vboID;
glGenBuffers(1, &vboID);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangle), triangle, GL_STATIC_DRAW);
// vertex position
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), 0);
// vertex color
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (char*)(3 * sizeof(float)));
}
bool checkStatus(
GLuint objectID,
PFNGLGETSHADERIVPROC objectPropertyGetterFunc,
PFNGLGETSHADERINFOLOGPROC getInfoLogFunc,
GLenum statusType)
{
GLint status;
objectPropertyGetterFunc(objectID, statusType, &status);
if (status != GL_TRUE)
{
GLint infoLogLength;
objectPropertyGetterFunc(objectID, GL_INFO_LOG_LENGTH, &infoLogLength);
GLchar* buffer = new GLchar[infoLogLength];
GLsizei bufferSize;
getInfoLogFunc(objectID, infoLogLength, &bufferSize, buffer);
std::cout << buffer << std::endl;
delete[] buffer;
return false;
}
return true;
}
bool checkShaderStatus(GLuint shaderID) {
return checkStatus(shaderID, glGetShaderiv, glGetShaderInfoLog, GL_COMPILE_STATUS);
}
bool checkProgramStatus(GLuint programID) {
return checkStatus(programID, glGetProgramiv, glGetProgramInfoLog, GL_LINK_STATUS);
}
std::string readShaderCode(const char* fileName) {
std::ifstream meInput(fileName);
if (!meInput.good()) {
std::cout << "File failed to load ... " << fileName << std::endl;
exit(1);
}
return std::string(
std::istreambuf_iterator<char>(meInput),
std::istreambuf_iterator<char>()
);
}
void installShaders() {
GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
const GLchar* adapter[1];
//adapter[0] = vertexShaderCode;
std::string temp = readShaderCode("VertexShaderCode.glsl");
adapter[0] = temp.c_str();
glShaderSource(vertexShaderID, 1, adapter, 0);
//adapter[0] = fragmentShaderCode;
temp = readShaderCode("FragmentShaderCode.glsl");
adapter[0] = temp.c_str();
glShaderSource(fragmentShaderID, 1, adapter, 0);
glCompileShader(vertexShaderID);
glCompileShader(fragmentShaderID);
if (!checkShaderStatus(vertexShaderID) || !checkShaderStatus(fragmentShaderID))
return;
programID = glCreateProgram();
glAttachShader(programID, vertexShaderID);
glAttachShader(programID, fragmentShaderID);
glLinkProgram(programID);
if (!checkProgramStatus(programID))
return;
glUseProgram(programID);
}
void initializedGL(void) {
// run only once
sendDataToOpenGL();
installShaders();
}
void paintGL(void) {
// always run
glClearColor(0.3f, 0.3f, 0.3f, 1.0f); //specify the background color
glClear(GL_COLOR_BUFFER_BIT);
glm::mat4 model = glm::mat4(1.0f);
model = glm::rotate(model, angle, glm::vec3(0.0f, 0.0f, 1.0f));
model = glm::translate(model, glm::vec3(x_delta * x_press_num, x_delta * y_press_num, 0.0f));
model = glm::scale(model, glm::vec3(size));
glUniformMatrix4fv(glGetUniformLocation(programID, "model"), 1, GL_FALSE, &model[0][0]);
glDrawArrays(GL_TRIANGLES, 0, 6); //render primitives from array data
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
if (key == GLFW_KEY_A && action == GLFW_PRESS) {
x_press_num -= 1;
}
if (key == GLFW_KEY_D && action == GLFW_PRESS) {
x_press_num += 1;
}
if (key == GLFW_KEY_W && action == GLFW_PRESS) {
y_press_num += 1;
}
if (key == GLFW_KEY_S && action == GLFW_PRESS) {
y_press_num -= 1;
}
if (key == GLFW_KEY_UP && action == GLFW_PRESS) {
size += glm::vec3(0.1f);
}
if (key == GLFW_KEY_DOWN && action == GLFW_PRESS) {
size -= glm::vec3(0.1f);
}
if (key == GLFW_KEY_LEFT && action == GLFW_PRESS) {
angle += 1.0f;
}
if (key == GLFW_KEY_RIGHT && action == GLFW_PRESS) {
angle -= 1.0f;
}
}
int main(int argc, char* argv[]) {
GLFWwindow* window;
/* Initialize the glfw */
if (!glfwInit()) {
std::cout << "Failed to initialize GLFW" << std::endl;
return -1;
}
/* glfw: configure; necessary for MAC */
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
/* do not allow resizing */
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(1600, 1600, "Hello Triangle", NULL, NULL);
if (!window) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwSetKeyCallback(window, key_callback);
/* Initialize the glew */
if (GLEW_OK != glewInit()) {
std::cout << "Failed to initialize GLEW" << std::endl;
return -1;
}
get_OpenGL_info();
initializedGL();
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window)) {
/* Render here */
paintGL();
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
顶点着色器:
#version 430
in layout(location=0) vec3 position;
in layout(location=1) vec3 vertexColor;
uniform mat4 model;
out vec3 theColor;
void main()
{
vec4 v = vec4(position, 1.0);
vec4 out_position = model * v;
gl_Position = out_position;
theColor = vertexColor;
}
片段着色器:
#version 430
out vec4 Color;
in vec3 theColor;
void main()
{
Color = vec4(theColor, 1.0);
}