• OpenGL红宝书第一个例子:绘制两个三角形


    1. 环境配置

    在这里不在做环境配置的说明,因为网上可以找到很多类似的教程,如果有需要可以@我,我也希望能帮到大家,其它的不说了,先上我的代码

    2. 第一个程序代码

    • 创建LoadShader.h
    #pragma once
    #include <GL/glew.h>
    #include <GLFW/glfw3.h>
    #include <string>
    
    GLuint LoadShader(const char *vertice_path, const char *framgment_path);
    bool compileShader(GLuint &shader_id, const char *path);
    
    static const GLchar *getFileData(const char * path);
    
    • 创建LoadShader.cpp
    #include "LoadShader.h"
    #include <fstream>
    #include <vector>
    
    GLuint LoadShader( const char *vertice_path, const char *framgment_path )
    {
    	GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
    	GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
    
    	bool bRet = compileShader(vertexShaderID, vertice_path);
    	if(!bRet)
    		return 0;
    	bRet = compileShader(fragmentShaderID, framgment_path);
    	if(!bRet)
    		return 0;
    
    	GLuint ProgramID = glCreateProgram();
    	glAttachShader(ProgramID, vertexShaderID);
    	glAttachShader(ProgramID, fragmentShaderID);
    	glLinkProgram(ProgramID);
    
    	glDeleteShader(vertexShaderID);
    	glDeleteShader(fragmentShaderID);
    
    	return ProgramID;
    }
    
    static const GLchar* getFileData( const char * path )
    {
    	FILE* infile;
    	fopen_s(&infile, path, "rb");
    	if(!infile)
    	{
    		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);
    }
    
    bool compileShader( GLuint &shader_id, const char *path )
    {
    	const GLchar *shader_code = getFileData(path);
    	if(strlen(shader_code) <= 0 )
    		return 0;
    
    	GLint Result = GL_FALSE;
    	GLint InfoLogLength;
    
    	glShaderSource(shader_id, 1, &shader_code, NULL);
    	glCompileShader(shader_id);
    
            delete []shader_code;
    
    	glGetShaderiv(shader_id, GL_COMPILE_STATUS, &Result);
    	if ( !Result ){
    		glGetShaderiv(shader_id, GL_INFO_LOG_LENGTH, &InfoLogLength);
    		std::vector<char> ShaderErrorMessage(InfoLogLength+1);
    		glGetShaderInfoLog(shader_id, InfoLogLength, NULL, &ShaderErrorMessage[0]);
    		printf("%s
    ", &ShaderErrorMessage[0]);
    		return false;
    	}
    
    	return true;
    }
    
    
    • OpenGL主逻辑文件triangles.cpp
    #include <iostream>
    #include "LoadShader.h"
    
    GLFWwindow *window;
    
    enum VAO_IDs { Triangles, NumVAOs };
    enum Buffer_IDs { ArrayBuffer, NumBuffers };
    enum Attrib_IDs { vPosition = 0 };
    
    GLuint VAOs[NumVAOs];
    GLuint Buffers[NumBuffers];
    
    const GLuint NumVertices = 6;
    GLuint shader_program;
    
    void init()
    {
    	glGenVertexArrays(NumVAOs,VAOs);
    	glBindVertexArray(VAOs[Triangles]);
    
    	GLfloat vertices[NumVertices][2] = {
    		{ -0.90f, -0.90f },
    		{  0.85f, -0.90f },
    		{ -0.90f,  0.85f },
    		{  0.90f, -0.85f },
    		{  0.90f,  0.90f },
    		{ -0.85f,  0.90f }
    	};
    
    	glGenBuffers(NumVertices, Buffers);
    	glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);
    	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
    	shader_program = LoadShader("triangles.vert", "triangles.frag");
    	glUseProgram(shader_program);
    	glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, (void *)0);
    	glEnableVertexAttribArray(vPosition);
    }
    
    void display()
    {
    	while (!glfwWindowShouldClose(window))
    	{
    		/* Render here */
    		glClear(GL_COLOR);
    		glBindVertexArray(VAOs[Triangles]);
    		glDrawArrays(GL_TRIANGLES, 0, NumVertices);
    
    		/* Swap front and back buffers */
    		glfwSwapBuffers(window);
    
    		/* Poll for and process events */
    		glfwPollEvents();
    	}
    
    	glfwTerminate();
    }
    
    int main(int argc, char** argv)
    {
    	if(!glfwInit())
    		return -1;
    
    	glfwWindowHint(GLFW_SAMPLES, 4);
    	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    
    	window = glfwCreateWindow(512, 512, "Hello World", NULL, NULL);
    	if(!window)
    	{
    		glfwTerminate();
    		return -1;
    	}
    	
    	glfwMakeContextCurrent(window);
    
    	// Initialize GLEW
    	glewExperimental = true; // Needed for core profile
    	if( GLEW_OK != glewInit())
    		return -1;
    
    	init();
    
    	display();
    
    	return 0;
    }
    
    • 顶点shader
    #version 330 core
    
    // Input vertex data, different for all executions of this shader.
    layout(location = 0) in vec4 vPosition;
    
    void main(){
    
        gl_Position = vPosition;
    }
    
    • 片段shader
    #version 330 core
    
    // Ouput data
    out vec4 fcolor;
    
    void main()
    {
    
    	fcolor = vec4(0.0, 0.0, 1.0, 1.0);
    
    }
    

    3.我在编写程序的时候遇到的问题

    3.1 因为例子是用4.3的,在我电脑上我用glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);设置后就会失败,后来改成了3.3就成功了,不知道原因,我猜测可能我的电脑不支持4.3的OpenGL

    3.2 写shader加载的时候遇到了点问题,glGetShaderiv(shader_id, GL_COMPILE_STATUS, &Result);没有看仔细glGetShaderiv的参数说明:Result正确的时候返回的是true,否则返回false,程序写反了,所以一直加载shader失败

    第一个OpenGL程序到这里就结束了。后续努力中。。。
    注: 后续的shader加载就不在说明,只有在添加的时候新内容的时候才会再次说明

  • 相关阅读:
    Compiling LIBFFM On OSX 10.9
    Linux shell 脚本入门教程+实例
    Understanding the Bias-Variance Tradeoff
    Learning How To Code Neural Networks
    MXNet设计和实现简介
    数据需求统计常用awk命令
    Deal with relational data using libFM with blocks
    MATLAB 在同一个m文件中写多个独立的功能函数
    Debug 路漫漫-06
    MATLAB 求两个矩阵的 欧氏距离
  • 原文地址:https://www.cnblogs.com/zjzyh/p/4666728.html
Copyright © 2020-2023  润新知