#include <stdio.h>#include <string.h>#include <assert.h>#include <math.h>#include <GL/glew.h>#include <GL/freeglut.h>#include "math_3d.h"#pragma comment(lib, "glew32.lib")#pragma comment(lib, "glew32mx.lib")#pragma comment(lib, "freeglut.lib")GLuint VBO;GLuint gWorldLocation;static float gScale = 0.0f;static const char *pVS = " \n\#version 330 \n\ \n\layout (location = 0) in vec3 Position; \n\ \n\uniform mat4 gWorld; \n\ \n\void main() \n\{ \n\ gl_Position = gWorld * vec4(Position, 1.0); \n\}";static const char *pFS = " \n\#version 330 \n\ \n\out vec4 FragColor; \n\ \n\void main() \n\{ \n\ FragColor = vec4(1.0, 0.0, 0.0, 1.0); \n\}";static void RenderSceneCB(){ glClear(GL_COLOR_BUFFER_BIT); //Scale += 0.001f; Matrix4f World;World.m[0][0] = 1.0f; World.m[0][1] = 0.0f; World.m[0][2] = 0.0f; World.m[0][3] = gScale;World.m[1][0] = 0.0f; World.m[1][1] = 1.0f; World.m[1][2] = 0.0f; World.m[1][3] = 0.0f;World.m[2][0] = 0.0f; World.m[2][1] = 0.0f; World.m[2][2] = 1.0f; World.m[2][3] = 0.0f;World.m[3][0] = 0.0f; World.m[3][1] = 0.0f; World.m[3][2] = 0.0f; World.m[3][3] = 1.0f; glUniformMatrix4fv(gWorldLocation, 1, GL_TRUE, &World.m[0][0]); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, VBO); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glDrawArrays(GL_TRIANGLES, 0, 3); glDisableVertexAttribArray(0); glutSwapBuffers();}static void ProcessKeyboard(unsigned char key, int x, int y){ switch (key) { case 'a': { gScale -= 0.01f; if (gScale < -1) { gScale = -1; } } break; case 'd': { gScale += 0.01f; if (gScale > 1) { gScale = 1; } } break; case 27: exit(0); } //标记当前窗口需要重新绘制。 //通过glutMainLoop下一次循环时,窗口显示将被回调以重新显示窗口的正常面板。 //多次调用glutPostRedisplay,在下一个显示回调只产生单一的重新显示回调。 glutPostRedisplay();}static void ProcessSpecialKeys(int key, int x, int y){ switch (key) { case GLUT_KEY_LEFT: { gScale -= 0.01f; if (gScale < -1) { gScale = -1; } } break; case GLUT_KEY_RIGHT: { gScale += 0.01f; if (gScale > 1) { gScale = 1; } } break; } glutPostRedisplay();}static void ProcessMouse(int button, int state, int x, int y){ if (button == GLUT_RIGHT_BUTTON && state == GLUT_UP) { glBindBuffer(GL_ARRAY_BUFFER, 0); float win_width = glutGet(GLUT_WINDOW_WIDTH); float win_height = glutGet(GLUT_WINDOW_HEIGHT); float x_pos = (float)x / win_width - 0.5f; float y_pos = 0.5f - (float)y / win_height; Vector3f Vertices[3]; Vertices[0] = Vector3f(x_pos - 0.5f, y_pos - 0.5f, 0.0f); Vertices[1] = Vector3f(x_pos + 0.5f, y_pos - 0.5f, 0.0f); Vertices[2] = Vector3f(x_pos, y_pos + 0.5, 0.0f); //glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); }}static void InitializeGlutCallbacks(){ glutDisplayFunc(RenderSceneCB);//注册显示回调 glutIdleFunc(RenderSceneCB);//空闲时回调 glutSpecialFunc(ProcessSpecialKeys); glutKeyboardFunc(ProcessKeyboard); glutMouseFunc(ProcessMouse);}static void CreateVertexBuffer(){ Vector3f Vertices[3]; Vertices[0] = Vector3f(-0.5f, -0.5f, 0.0f); Vertices[1] = Vector3f(0.5f, -0.5f, 0.0f); Vertices[2] = Vector3f(0.0f, 0.5f, 0.0f); glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);}static void AddShader(GLuint ShaderProgram, const char *pShaderText, GLenum ShaderType){ GLuint ShaderObj = glCreateShader(ShaderType); if (ShaderObj == 0) { fprintf(stderr, "Error creating shader type %d\n", ShaderType); exit(0); } const GLchar *p[1]; p[0] = pShaderText; GLint Lengths[1]; Lengths[0] = strlen(pShaderText); glShaderSource(ShaderObj, 1, p, Lengths); glCompileShader(ShaderObj); GLint success; glGetShaderiv(ShaderObj, GL_COMPILE_STATUS, &success); if (!success) { GLchar InfoLog[1024]; glGetShaderInfoLog(ShaderObj, 1024, NULL, InfoLog); fprintf(stderr, "Error compiling shader type %d: '%s'\n", ShaderType, InfoLog); exit(1); } glAttachShader(ShaderProgram, ShaderObj);}static void CompileShaders(){ GLuint ShaderProgram = glCreateProgram(); if (ShaderProgram == 0) { fprintf(stderr, "Error creating shader program\n"); exit(1); } AddShader(ShaderProgram, pVS, GL_VERTEX_SHADER); AddShader(ShaderProgram, pFS, GL_FRAGMENT_SHADER); GLint Success = 0; GLchar ErrorLog[1024] = { 0 }; glLinkProgram(ShaderProgram); glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &Success); if (Success == 0) { glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog); fprintf(stderr, "Error linking shader program: '%s'\n", ErrorLog); exit(1); } glValidateProgram(ShaderProgram); glGetProgramiv(ShaderProgram, GL_VALIDATE_STATUS, &Success); if (!Success) { glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog); fprintf(stderr, "Invalid shader program: '%s'\n", ErrorLog); exit(1); } glUseProgram(ShaderProgram); gWorldLocation = glGetUniformLocation(ShaderProgram, "gWorld"); assert(gWorldLocation != 0xFFFFFFFF);}int main(int argc, char **argv){ glutInit(&argc, argv);//gultInit用于初始化GULT库 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); glutInitWindowSize(1024, 768); glutInitWindowPosition(100, 100); glutCreateWindow("Tutorial 06"); InitializeGlutCallbacks(); // Must be done after glut is initialized! GLenum res = glewInit();//使用glewInit()函数导出所有显卡支持的函数 if (res != GLEW_OK) { fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res)); return 1; } glClearColor(0.0f, 0.0f, 0.0f, 0.0f); CreateVertexBuffer(); CompileShaders(); glutMainLoop(); return 0;}