OpenGL中shader读取实现

1.需要shader在OpenGL中工作,必须经过如下过程

2.代码实现

/**********
* loadshader.h
**********/
#pragma once

#define _CRT_SECURE_NO_WARNINGS 1
#define WIN32_LEAN_AND_MEAN 1
#define GLFW_NO_GLU 1


#include <Windows.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <cmath>
#include <iostream>
#include <stdio.h>
#include <string.h>
#define GLFW_INCLUDE_GLCOREARB 1

GLuint CreateShaderProgram();
GLuint LoadShader(const char *shader_path, GLenum shader_type);
void LinkShader(GLuint shader_pragram, ...);  /// 以0结束
bool compileShader(GLuint &shader_id, const char *path);

static const GLchar *getFileData(const char * path);

static const int MAX_LOG_LEN = 16 * 1024;

static void _log(const char *format, va_list args)
{
	char buf[MAX_LOG_LEN];
	vsnprintf(buf, MAX_LOG_LEN - 3, format, args);
	strcat(buf, "\n");

	WCHAR wszBuf[MAX_LOG_LEN] = {0};
	MultiByteToWideChar(CP_UTF8, 0, buf, -1, wszBuf, sizeof(wszBuf));
	OutputDebugStringW(wszBuf);
	WideCharToMultiByte(CP_ACP, 0, wszBuf, -1, buf, sizeof(buf), nullptr, FALSE);
	printf("%s", buf);
	fflush(stdout);
}

void log(const char *format, ...);


/**********
* loadshader.cpp
**********/
#include "LoadShader.h"
#include <fstream>
#include <vector>

GLuint LoadShader( const char *shader_path, GLenum shader_type )
{
	GLuint shader_id = glCreateShader(shader_type);

	bool bRet = compileShader(shader_id, shader_path);
	if(!bRet)
	{
		glDeleteShader(shader_id);
		return 0;
	}
	
	return shader_id;
}

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\n", &ShaderErrorMessage[0]);
		log("%s", &ShaderErrorMessage[0]);
		return false;
	}

	return true;
}

void log( const char *format, ... )
{
	va_list args;
	va_start(args, format);
	_log(format, args);
	va_end(args);
}

bool LoadTessellationShader( GLuint shader_program, const char *tes_shader_path )
{
	GLuint shader = glCreateShader(GL_TESS_CONTROL_SHADER);
	bool bRet = compileShader(shader, tes_shader_path);
	if(!bRet)
		return false;
	glAttachShader(shader_program, shader);
	glLinkProgram(shader_program);

	glDeleteProgram(shader);
	
	return true;
}

void LinkShader( GLuint shader_pragram, ... )
{
	va_list args;
	va_start(args, shader_pragram);
	while (true)
	{
		GLuint shader_id = va_arg(args, GLuint);
		if(shader_id <= 0)
			break;
		glAttachShader(shader_pragram, shader_id);
		glDeleteShader(shader_id);
	}
	va_end(args);
	glLinkProgram(shader_pragram);
}

GLuint CreateShaderProgram()
{
	return glCreateProgram();
}


posted @ 2015-08-13 16:50  zyh_think  阅读(2124)  评论(0编辑  收藏  举报