使用opengl的geometry总结及其源代码

遇到两个问题:

(1)如果geometry shader 文件不加上#version 450 core,compile shader source会报错;

(2)使用GLFW创建窗口时,不添加glewExperimental = GL_TRUE,使用glGenVertexArrays(1, &vao),直接崩溃

(3)创建GL_GEOMETRY_SHADER,找不到该变量,更新glew包到1.3版本即可

(4)使用glew 1.3版本和glut创建应用程序无法启动,使用glfw库来替代,原来的glut过于老了。

源代码如下:

basic.vert (vertex shader)

#version 450 core

in vec2 pos;

void main()
{
	gl_Position = vec4(pos, 0.0, 1.0);
}
basic.geom(geometry shader)
#version 450 core

in vec2 pos;

void main()
{
	gl_Position = vec4(pos, 0.0, 1.0);
}
basic.frag(fragment shader)

#version 450 core

out vec4 outColor;

void main()
{
	outColor = vec4(1.0, 0.0, 0.0, 1.0);
}


读取文件FileManager.h/FileManager.cpp
class FileManager
{

public:
	FileManager();
	~FileManager();

public:

	unsigned char* readDataFromFile(char* fn);

	char* textFileRead(const char* fn);

	int textFileWrite(char* fn, char* s);

};
#include "stdafx.h"
#include "FileManager.h"
#include <iostream>


FileManager::FileManager()
{
}


FileManager::~FileManager()
{
}

unsigned char* FileManager::readDataFromFile(char* fn)
{
	FILE *fp;
	unsigned char *content = NULL;

	int count = 0;

	if (fn != NULL) {
		fopen_s(&fp, fn, "rb");

		if (fp != NULL) {

			fseek(fp, 0, SEEK_END);
			count = ftell(fp);
			rewind(fp);

			if (count > 0) {
				content = (unsigned char *)malloc(sizeof(unsigned char) * (count + 1));
				count = fread(content, sizeof(unsigned char), count, fp);
				content[count] = '\0';
			}
			fclose(fp);
		}
	}
	return content;
}

char* FileManager::textFileRead(const char* fn)
{
	FILE *fp;
	char *content = NULL;

	int count = 0;

	if (fn != NULL) {
		fopen_s(&fp, fn, "rt");

		if (fp != NULL) {

			fseek(fp, 0, SEEK_END);
			count = ftell(fp);
			rewind(fp);

			if (count > 0) {
				content = (char *)malloc(sizeof(char) * (count + 1));
				count = fread(content, sizeof(char), count, fp);
				content[count] = '\0';
			}
			fclose(fp);
		}
	}
	return content;
}

int FileManager::textFileWrite(char* fn, char* s)
{
	FILE *fp;
	int status = 0;

	if (fn != NULL) {
		fopen_s(&fp, fn, "w");

		if (fp != NULL) {

			if (fwrite(s, sizeof(char), strlen(s), fp) == strlen(s))
				status = 1;
			fclose(fp);
		}
	}
	return(status);
}




shader管理类ShaderManager.h/.cpp

#include <iostream>
#include "FileManager.h"
#include <gl/glew.h>
#include <gl/GL.h>

using namespace std;

class ShaderManager
{
public:
	ShaderManager();

	~ShaderManager();

public:

	void BuildShader(const char* VShaderFile,
		             const char* GShaderFile,
					 const char* FShaderFile);
	
	GLuint GetProgram();

	void ShowShaderInfo();

public:
	GLuint m_vShader;
	GLuint m_fShader;
	GLuint m_gShader;

	GLuint m_Program;

public:
	FileManager m_FileManager;
};

#include "stdafx.h"
#include "ShaderManager.h"


ShaderManager::ShaderManager()
{
}


ShaderManager::~ShaderManager()
{
}

void ShaderManager::ShowShaderInfo()
{
	const GLubyte *renderer = glGetString(GL_RENDERER);
	const GLubyte *vendor = glGetString(GL_VENDOR);
	const GLubyte *version = glGetString(GL_VERSION);
	const GLubyte *glslVersion =
		glGetString(GL_SHADING_LANGUAGE_VERSION);
	GLint major, minor;
	glGetIntegerv(GL_MAJOR_VERSION, &major);
	glGetIntegerv(GL_MINOR_VERSION, &minor);
	cout << "GL Vendor    :" << vendor << endl;
	cout << "GL Renderer  : " << renderer << endl;
	cout << "GL Version (string)  : " << version << endl;
	cout << "GL Version (integer) : " << major << "." << minor << endl;
	cout << "GLSL Version : " << glslVersion << endl;
}

void ShaderManager::BuildShader(const char* VShaderFile,
	const char* GShaderFile,
	const char* FShaderFile)
{   
	ShowShaderInfo();

	m_vShader = glCreateShader(GL_VERTEX_SHADER);
	if (m_vShader == 0)
	{
		cerr << "Error: Create vertex shader failed!" << endl;
		return;
	}

	const GLchar* vShaderSource = m_FileManager.textFileRead(VShaderFile);
	const GLchar* vCodeArray[1] = {vShaderSource};
	glShaderSource(m_vShader, 1, vCodeArray, NULL);
	glCompileShader(m_vShader);
	
	GLint compileResult;
	glGetShaderiv(m_vShader, GL_COMPILE_STATUS, &compileResult);
	if (compileResult == GL_FALSE)
	{
		cerr << "Error: Compile vertex shader failed!" << endl;
		return;
	}

	m_gShader = glCreateShader(GL_GEOMETRY_SHADER);
	if (0 == m_gShader)
	{
		cerr << "ERROR: Create geometry failed!" << endl;
		return;
	}
	const GLchar* gShaderCode = m_FileManager.textFileRead(GShaderFile);
	const GLchar* gCodeArray[1] = { gShaderCode };

	glShaderSource(m_gShader, 1, gCodeArray, NULL);
	glCompileShader(m_gShader);

	glGetShaderiv(m_gShader, GL_COMPILE_STATUS, &compileResult);
	if (compileResult == GL_FALSE)
	{
		cerr << "ERROR: compile geometry failed!" << endl;

		GLint logLen;

		glGetShaderiv(m_gShader, GL_INFO_LOG_LENGTH, &logLen);
		if (logLen > 0)
		{
			char *log = (char *)malloc(logLen);
			GLsizei written;
			
			glGetShaderInfoLog(m_gShader, logLen, &written, log);
			cerr << "vertex shader compile log : " << endl;
			cerr << log << endl;
			free(log);
		}

		return;
	}

	m_fShader = glCreateShader(GL_FRAGMENT_SHADER);
	if (0 == m_fShader)
	{
		cerr << "ERROR: Create fragment shader failed!" << endl;
		return;
	}

	const GLchar* fShaderCode = m_FileManager.textFileRead(FShaderFile);
	const GLchar* fCodeArray[1] = { fShaderCode };
	glShaderSource(m_fShader, 1, fCodeArray, NULL);

	glCompileShader(m_fShader);

	glGetShaderiv(m_fShader, GL_COMPILE_STATUS, &compileResult);
	if (compileResult == GL_FALSE)
	{
		cerr << "Error: Compile fragment shader failed!" << endl;
		return;
	}

	m_Program = glCreateProgram();

	if (0 == m_Program)
	{
		cerr << "ERROR: Create Program failed!" << endl;
		return;
	}

	glAttachShader(m_Program, m_vShader);
	glAttachShader(m_Program, m_gShader);
	glAttachShader(m_Program, m_fShader);

	glLinkProgram(m_Program);
	GLint linkStatus;
	glGetProgramiv(m_Program, GL_LINK_STATUS, &linkStatus);
	if (GL_FALSE == linkStatus)
	{
		cerr << "ERROR: Link the program failed!" << endl;
		return;
	}
	
	glUseProgram(m_Program);
}

GLuint ShaderManager::GetProgram()
{
	return m_Program;
}
程序入口main.cpp

// testOpenGL.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>

#define  GLEW_STATIC
#include "glew.h"
#include "glfw3.h"
#include "ShaderManager.h"

const GLuint WIDTH = 800;
const GLuint HEIGHT = 600;

ShaderManager shaderManager;

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
	std::cout << key << std::endl;
	if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
	{
		glfwSetWindowShouldClose(window, GL_TRUE);
	}
}

void initData()
{   
	// 
	GLuint vbo;
	glGenBuffers(1, &vbo);

	float points[] =
	{
		-0.45f, 0.45f,
		0.45f, 0.45f,
		0.45f, -0.45f,
		-0.45f, -0.45f,
	};

	glBindBuffer(GL_ARRAY_BUFFER, vbo);
	glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);

	GLuint vao = 0;
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);

	GLint posAttrib = glGetAttribLocation(shaderManager.GetProgram(), "pos");
	glEnableVertexAttribArray(posAttrib);
	glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
}


int _tmain(int argc, _TCHAR* argv[])
{
	std::cout << "Starting GFLEW context, OpenGL 3.3" << std::endl;
	glfwInit();

	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

	GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "Test GLFW Lib", NULL, NULL);
	if (window == NULL)
	{
		std::cout << "Failed to create GLFW window!" << std::endl;
		glfwTerminate();
		return -1;
	}

	glfwMakeContextCurrent(window);

	glfwSetKeyCallback(window, key_callback);

	glewExperimental = GL_TRUE;

	if (glewInit() != GLEW_OK)
	{
		std::cout << "Failed to initialize GLEW" << std::endl;
		return -1;
	}

	glViewport(0, 0, WIDTH, HEIGHT);

	// 创建shader对象
	shaderManager.BuildShader("basic.vert", "basic.geom", "basic.frag");

	initData();

	while (!glfwWindowShouldClose(window))
	{
		glfwPollEvents();

		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		glDrawArrays(GL_POINTS, 0, 4);

		glfwSwapBuffers(window);
	}

	glfwTerminate();

	return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值