OpenGL实践的部分心得
前言:根据cherno的课程学习,
VS调试警告
输出栏警告:严重性 代码 说明 项目 文件 行 禁止显示状态 警告 LNK4098 默认库“LIBCMT”与其他库的使用冲突;请使用 /NODEFAULTLIB:library
处理方法:右键项目属性,进入链接器中的输入,在忽略特定默认库中填入libcmt.lib,应用即可
ShaderProgramSource ParseShader(string filepath) {
ifstream stream(filepath);
enum class ShaderType {
NONE = -1, VERTEX = 0, FRAGMENT = 1
};
string line;
stringstream ss[2];
ShaderType type = ShaderType::NONE;
while (getline(stream, line))
{
if (line.find("#shader") != string::npos)
{
if (line.find("vertex") != string::npos)
{
//设置模式为顶点
type = ShaderType::VERTEX;
}
else if (line.find("fragment") != string::npos)
{
//设置模式为片段
type = ShaderType::FRAGMENT;
}
}
else {
if ((int)type >= 0) //不写会引发异常
ss[(int)type] << line << "\n";
}
}
return { ss[0].str(),ss[1].str() };
}
在OpenGL中处理错误
1.宏定义
#define ASSERT(x) if(!x) __debugbreak() // _debugbreak()这个会报错(原因__两个下划线)
#define ASSERT(x) if(!(x)) __debugbreak() //#define ASSERT(x) if (!(x)) _debugbreak();这个会报错(原因__两个下划线)
#define GLCall(x) GLClearError();\
x;\
ASSERT(GLLogCall(#x,__FILE__,__LINE__))
//#define GLCall(x) GLClearError();\
// x;\
// ASSERT(GLLogCall);
static void GLClearError() {
while (glGetError() != GL_NO_ERROR);
};
static void GLCheckError() {
while (GLenum error = glGetError()) {
std::cout << "[OpenGL_Error(" << error << ")]" << std::endl;
}
}
static bool GLLogCall(const char* function,const char* file,int line) {
while (GLenum error = glGetError()) {
std::cout << "[OpenGL_Error(" << error << ")]" << ":" << function << "\t" << "line:" << line << std::endl;
return false;
}
return true;
};
struct ShaderProgramSource{
string VertexSource;
string FragmentSource;
};
ShaderProgramSource ParseShader(string filepath) {
ifstream stream(filepath);
enum class ShaderType {
NONE = -1, VERTEX = 0, FRAGMENT = 1
};
string line;
stringstream ss[2];
ShaderType type = ShaderType::NONE;
while (getline(stream, line))
{
if (line.find("#shader") != string::npos)
{
if (line.find("vertex") != string::npos)
{
//设置模式为顶点
type = ShaderType::VERTEX;
}
else if (line.find("fragment") != string::npos)
{
//设置模式为片段
type = ShaderType::FRAGMENT;
}
}
else {
if ((int)type >= 0) //不写会引发异常
ss[(int)type] << line << "\n";
}
}
return { ss[0].str(),ss[1].str() };
}
static unsigned int CompileShader(unsigned int type,const string& source) {
unsigned int id = glCreateShader(type);
const char* src = source.c_str();
glShaderSource(id, 1, &src, nullptr);
glCompileShader(id);
int result;
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
if (result == GL_FALSE) {
int length;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
char* message = (char*)_malloca(length * sizeof(char));
glGetShaderInfoLog(id, length, &length, message);
cout << "Failed to compile" <<
(type == GL_VERTEX_SHADER? "vertex":"fragment")
<< "shader" << endl;
cout << message << endl;
glDeleteShader(id);
return 0;
}
return id;
}
static unsigned int Creatshader(const string& vertexShader, const string& fragmentShader) {
unsigned int program = glCreateProgram();
unsigned int vs = CompileShader(GL_VERTEX_SHADER,vertexShader);
unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glValidateProgram(program);
glDeleteShader(vs);
glDeleteShader(fs);
return program;
}
int main(void)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK);
cout << "Error!" << endl;
cout << glGetString(GL_VERSION) << endl;
float positions[] = {
-0.5f,-0.5f,//0
0.5f,-0.5f,//1
0.5f,0.5f,//2
/*
0.5,0.5,
-0.5,-0.5,*/
-0.5f,0.5f //因为有些点重复占用显存,所以建立索引缓冲区
};
unsigned int indices[] = {
0,1,2,
2,3,0
};
unsigned int buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 12*sizeof(float),positions,GL_STATIC_DRAW); //12个点坐标
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float)*2, 0);
unsigned int ibo; //绑定索引缓冲区
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned int), indices, GL_STATIC_DRAW); //12个点坐标
ShaderProgramSource source = ParseShader("res/shaders/Basic.shader");
/* cout << "Vertex" << endl;
cout << source.VertexSource << endl;
cout << "Fragment" << endl;
cout << source.FragmentSource << endl;*/
unsigned int shader = Creatshader(source.VertexSource, source.FragmentSource);
//unsigned int shader = Creatshader(VertexShader, FragmentShader);
//GLCall(glUseProgram(shader));
glUseProgram(shader);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT); //清除屏幕
/* glBegin(GL_TRIANGLES);
glVertex2f(-0.5f,-0.5f);
glVertex2f(0.0f, 0.5f);
glVertex2f(0.5f, -0.5f);
glEnd();*/
//GLClearError();
//glDrawArrays(GL_TRIANGLES,0,6);//绘制6个顶点
//glDrawElements(GL_TRIANGLES, 6,GL_UNSIGNED_INT,nullptr);//绘制的6个索引数量,nullptr替代NULL,而NULL当做0使用
GLCall(glDrawElements(GL_TRIANGLES, 6, GL_INT, nullptr));
//ASSERT(GLLogCall());
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glDeleteProgram(shader);
glfwTerminate();
return 0;
}