3.OpenGL_第一个程序
在蓝宝书第一章中给出的程序,分了三个函数:init()、display()、main();
这三个函数也将成为后期学习的一个骨架。
/**********
*
* 作者 : Quaye
* 时间 : 2018.07.13
*
* 描述 : OpenGL骨架程序,TODO:未来更新为方便的shader测试文件
*
**/
#include "GL/glew.h"
#include "GLFW/glfw3.h"
#include <iostream>
#include <assert.h>
using namespace std;
const GLsizei NUM_VERTICS = 6;
// VAO : vertex array object;
const GLsizei NUM_VAOS = 1;
GLuint VAOs[NUM_VAOS];
const GLsizei NumBuffers = 1;
GLuint Buffer[NumBuffers];
const GLsizei vPosition = 0;
// loadShader 这一部分直接copy过来,暂时不考虑里面的内容。只为了方便加载shader文件
#pragma region loadShader
typedef struct {
GLenum type;
const char* filename;
GLuint shader;
} ShaderInfo;
static const GLchar*
ReadShader(const char* filename)
{
#ifdef WIN32
FILE* infile;
fopen_s(&infile, filename, "rb");
#else
FILE* infile = fopen(filename, "rb");
#endif // WIN32
if (!infile) {
#ifdef _DEBUG
std::cerr << "Unable to open file '" << filename << "'" << std::endl;
#endif /* DEBUG */
return NULL;
}
fseek(infile, 0, SEEK_END);
int len = ftell(infile);
fseek(infile, 0, SEEK_SET);
GLchar* source = new GLchar[len + 1];
fread(source, 1, len, infile);
fclose(infile);
source[len] = 0;
return const_cast<const GLchar*>(source);
}
GLuint
LoadShaders(ShaderInfo* shaders)
{
if (shaders == NULL) { return 0; }
GLuint program = glCreateProgram();
ShaderInfo* entry = shaders;
while (entry->type != GL_NONE) {
GLuint shader = glCreateShader(entry->type);
entry->shader = shader;
const GLchar* source = ReadShader(entry->filename);
if (source == NULL) {
for (entry = shaders; entry->type != GL_NONE; ++entry) {
glDeleteShader(entry->shader);
entry->shader = 0;
}
return 0;
}
glShaderSource(shader, 1, &source, NULL);
delete[] source;
glCompileShader(shader);
GLint compiled;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
#ifdef _DEBUG
GLsizei len;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
GLchar* log = new GLchar[len + 1];
glGetShaderInfoLog(shader, len, &len, log);
std::cerr << "Shader compilation failed: " << log << std::endl;
delete[] log;
#endif /* DEBUG */
return 0;
}
glAttachShader(program, shader);
++entry;
}
}
#pragma endregion
void init()
{
glCreateVertexArrays(NUM_VAOS, VAOs);
glBindVertexArray(VAOs[0]);
GLfloat vertices[NUM_VERTICS][2] =
{
{ -0.90f, -0.90f },{ 0.85f, -0.90f },{ -0.90f, 0.85f }, // Triangle 1
{ 0.90f, -0.85f },{ 0.90f, 0.90f },{ -0.85f, 0.90f } // Triangle 2
};
glCreateBuffers(NumBuffers, Buffer);
glBindBuffer(GL_ARRAY_BUFFER, Buffer[0]);
glBufferStorage(GL_ARRAY_BUFFER, sizeof(vertices), vertices, 0);
ShaderInfo shaders[] =
{
{ GL_VERTEX_SHADER, "media/shaders/triangles/triangles.vert" },
{ GL_FRAGMENT_SHADER, "media/shaders/triangles/triangles.frag" },
{ GL_NONE, NULL }
};
GLuint program = LoadShaders(shaders);
glUseProgram(program);
glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(vPosition);
}
void display()
{
static const float black[] = { 0.0f, 0.0f, 0.0f, 0.0f };
glClearBufferfv(GL_COLOR, 0, black);
glBindVertexArray(VAOs[0]);
glDrawArrays(GL_TRIANGLES, 0, NUM_VERTICS);
}
int main()
{
// 初始化GLFW库,必须是第一调用的GLFW函数
glfwInit();
GLFWwindow * window = glfwCreateWindow(640, 480, "mytitle", NULL, NULL);
glfwMakeContextCurrent(window);
GLenum err = glewInit();
cout << "glew init code : " << err << endl;
if (GLEW_OK != err)
{
assert("glew init error:" + err);
}
const GLubyte * str = glGetString(GL_EXTENSIONS);
init();
while (!glfwWindowShouldClose(window))
{
display();
glfwSwapBuffers(window);
//获取系统事件?之后好好看下注释
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}