Opengl 来给三角形一点颜色看看
我们通过设置vertex shader和fragment shader来给三角形一点颜色。
#include "glew.h"
#include <glfw3.h>
#include "common/loadShader.h"
int main(void)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(480, 320, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
// Needed in core profile
if( glewInit() != GLEW_OK)
{
glfwTerminate();
return -1;
}
// An array of 3 vectors which represents 3 vertices
static const GLfloat g_vertex_buffer_data[] = {
-1.0f,-1.0f,0.0f,
1.0f,-1.0f,0.0f,
0.0f,1.0f,0.0f,
};
//This will identify our vertex buffer
GLuint vertexbuffer;
//Generate 1 buffer,put the resulting identifier in vertexbuffer
glGenBuffers(1,&vertexbuffer);
//The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer);
//Give our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER,sizeof(g_vertex_buffer_data),g_vertex_buffer_data,GL_STATIC_DRAW);
GLuint programID = LoadShaders("./shader/vertex.shader","./shader/fragment.shader");
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(programID);
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
glDrawArrays(GL_TRIANGLES,0,3);// Starting from vertex 0; 3 vertices total -> 1 triangle
glDisableVertexAttribArray(0);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
再来看看LoadShaders
GLuint LoadShaders(const char* vertex_file_path,const char* fragment_file_path)
{
//Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
//Read the Vertex Shader code from the file
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertex_file_path,std::ios::in);
if (VertexShaderStream.is_open())
{
std::string Line = "";
while (getline(VertexShaderStream,Line))
{
VertexShaderCode += "\n" + Line;
}
VertexShaderStream.close();
}
//Read the Fragment Shader code from the file
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path,std::ios::in);
if (FragmentShaderStream.is_open())
{
std::string Line = "";
while (getline(FragmentShaderStream,Line))
{
FragmentShaderCode += "\n" + Line;
}
FragmentShaderStream.close();
}
GLint Result = GL_FALSE;
int InfoLogLength;
//compile Vertex Shader
printf("Compiling shader : %s\n",vertex_file_path);
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID,1,&VertexSourcePointer,NULL);
glCompileShader(VertexShaderID);
// Check vertex Shader
glGetShaderiv(VertexShaderID,GL_COMPILE_STATUS,&Result);
glGetShaderiv(VertexShaderID,GL_INFO_LOG_LENGTH,&InfoLogLength);
std::vector<char> VerTexShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(VertexShaderID,InfoLogLength,NULL,&VerTexShaderErrorMessage[0]);
fprintf(stdout,"%s\n",&VerTexShaderErrorMessage[0]);
//compile Fragment Shader
printf("Compiling shader : %s\n",vertex_file_path);
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID,1,&FragmentSourcePointer,NULL);
glCompileShader(FragmentShaderID);
// Check vertex Shader
glGetShaderiv(FragmentShaderID,GL_COMPILE_STATUS,&Result);
glGetShaderiv(FragmentShaderID,GL_INFO_LOG_LENGTH,&InfoLogLength);
std::vector<char> FragmentShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(FragmentShaderID,InfoLogLength,NULL,&FragmentShaderErrorMessage[0]);
fprintf(stdout,"%s\n",&FragmentShaderErrorMessage[0]);
//Link the program
fprintf(stdout,"Linking programn");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID,VertexShaderID);
glAttachShader(ProgramID,FragmentShaderID);
glLinkProgram(ProgramID);
//Check the program
glGetProgramiv(ProgramID,GL_LINK_STATUS,&Result);
glGetProgramiv(ProgramID,GL_INFO_LOG_LENGTH,&InfoLogLength);
std::vector<char> ProgramErrorMessage(InfoLogLength);
glGetProgramInfoLog(ProgramID,InfoLogLength,NULL,&ProgramErrorMessage[0]);
fprintf(stdout,"%s\n",&ProgramErrorMessage[0]);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}
最后看看vertex.shader
#version 330 core
layout(location = 0) in vec3 vertexPosition_modelspace;
void main(){
gl_Position.xyz = vertexPosition_modelspace;
gl_Position.w = 1.0;
}
fragment.shader
out vec3 color;
void main(){
color = vec3(1,0,0);
}
首先,我们在循环之前,载入两个shader,顶点shader和片段shader.
GLuint programID = LoadShaders("./shader/vertex.shader","./shader/fragment.shader");
设置清理屏幕颜色 glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
在循环中,清理颜色glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
设置shader glUseProgram(programID);
设置shader glUseProgram(programID);
loadShaders主要是将文件中shader实时编译。
创建不同类型shader
//Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
读入每段,并以"\n"结尾。
//Read the Vertex Shader code from the file
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertex_file_path,std::ios::in);
if (VertexShaderStream.is_open())
{
std::string Line = "";
while (getline(VertexShaderStream,Line))
{
VertexShaderCode += "\n" + Line;
}
VertexShaderStream.close();
}
//Read the Fragment Shader code from the file
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path,std::ios::in);
if (FragmentShaderStream.is_open())
{
std::string Line = "";
while (getline(FragmentShaderStream,Line))
{
FragmentShaderCode += "\n" + Line;
}
FragmentShaderStream.close();
}
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertex_file_path,std::ios::in);
if (VertexShaderStream.is_open())
{
std::string Line = "";
while (getline(VertexShaderStream,Line))
{
VertexShaderCode += "\n" + Line;
}
VertexShaderStream.close();
}
//Read the Fragment Shader code from the file
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path,std::ios::in);
if (FragmentShaderStream.is_open())
{
std::string Line = "";
while (getline(FragmentShaderStream,Line))
{
FragmentShaderCode += "\n" + Line;
}
FragmentShaderStream.close();
}
编译shader,检查结果
链接shader
//Link the program
fprintf(stdout,"Linking programn");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID,VertexShaderID);
glAttachShader(ProgramID,FragmentShaderID);
glLinkProgram(ProgramID);
fprintf(stdout,"Linking programn");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID,VertexShaderID);
glAttachShader(ProgramID,FragmentShaderID);
glLinkProgram(ProgramID);
释放shader
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
glDeleteShader(FragmentShaderID);