用 glew 来学习 opengles

想系统的学习一下 opengles 就买了一本书《OpenglES 3.0 编程指南》。书中的例子支持在 Windows Linux 安卓等平台运行。由于个人平常开发环境是 Windows ,因此更倾向于在 Windows 上学习,最后再统一移植到安卓。编程

书上在 Windows 上编译采用的是高通的 Adreno SDK 。而后统一用的 cmake 来编译。我下载的 cmake 和 Adreno SDK 都是最新版的,而后按照书上的操做没有编译成功。就手动的用 vs 的命令行编译环境编译,可是容许时会提示没法加载 egl 的某个 API 虽然不影响最终的结果,仍是不爽。网上搜索了,也没有好的办法。因而想用 mingw32 来做为开发环境。xcode

之因此会选择 mingw32 是由于 ejoy2d 就支持用 mingw32 编译。而后窗口的建立我用的 freeglut 。因而最终用 mingw32 + glew + freeglut 成功运行了第一个实例。具体代码下所示。函数

#include <GL/glew.h>
#include <GL/freeglut.h>
#include <stdio.h>

#define logv printf

static GLuint _program;

/**
 * 加载并编译 shader 。
 */
static GLuint 
load_shader(GLenum shadertype, const GLchar *shadercode) {
	GLuint shader = glCreateShader(shadertype);
	if (shader == 0) {
		logv("Fail to create shader\n");
		return 0;
	}

	// 编译
	glShaderSource(shader, 1, &shadercode, NULL);
	glCompileShader(shader);

	// 检查编译结果
	GLint value = 0;
	glGetShaderiv(shader, GL_COMPILE_STATUS, &value);
	if (value == GL_FALSE) {
		value = 0;
		glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &value);
		if (value > 1) {
			GLchar info[value + 1];
			glGetShaderInfoLog(shader, value, NULL, info);
			logv("Fail to compile shader: %s\n", info);
		}
		glDeleteShader(shader);
	}

	return shader;
}

/**
 * 加载 shader 并连接。
 */
static GLuint 
link_programs(GLchar *vertexcode, GLchar *fragmentcode) {
	GLuint vertexshader = 0, fragmentshader = 0, program = 0;
	vertexshader = load_shader(GL_VERTEX_SHADER, vertexcode);
	if (vertexshader == 0) {
		logv("Fail to create vertex shader");
		goto EXIT;
	}
	fragmentshader  = load_shader(GL_FRAGMENT_SHADER, fragmentcode);
	if (fragmentshader == 0) {
		logv("Fail to create fragment shader");
		goto EXIT;
	}

	program = glCreateProgram();
	if (program == 0) {
		logv("Fail to create program");
		goto EXIT;
	}

	// 连接
	glAttachShader(program, vertexshader);
	glAttachShader(program, fragmentshader);
	glLinkProgram(program);

	// 查看连接结果
	GLint value = 0;
	glGetProgramiv(program, GL_LINK_STATUS, &value);
	if (value == GL_FALSE) {
		value = 0;
		glGetProgramiv(program, GL_INFO_LOG_LENGTH, &value);
		if (value > 1) {
			GLchar info[value];
			glGetProgramInfoLog(program, value, NULL, info);
			logv("Fail to link program: %s\n", info);
		}
		goto EXIT;
	}

	return program;
EXIT:
	if (vertexshader != 0)
		glDeleteShader(vertexshader);
	if (fragmentshader != 0)
		glDeleteShader(fragmentshader);
	if (program != 0)
		glDeleteProgram(program);
	return 0;
}

static GLboolean
init() {
	GLenum err = glewInit();
	if (err != GLEW_OK) {
		logv("Fail to init glew\n");
		return GL_FALSE;
	}

	GLchar vertexcode[] =
      "#version 300 es                          \n"
      "layout(location = 0) in vec4 vPosition;  \n"
      "void main()                              \n"
      "{                                        \n"
      "   gl_Position = vPosition;              \n"
      "}                                        \n";

   GLchar fragmentcode[] =
      "#version 300 es                              \n"
      "precision mediump float;                     \n"
      "out vec4 fragColor;                          \n"
      "void main()                                  \n"
      "{                                            \n"
      "   fragColor = vec4 (1.0, 0.0, 0.0, 1.0);    \n"
      "}                                            \n";

    _program = link_programs(vertexcode, fragmentcode);
    if (_program == 0)
    	return GL_FALSE;
    return GL_TRUE;
}

static void
cb_display() {
	logv("cb_display\n");
   	GLfloat vVertices[] = {0.0f, 0.5f, 0.0f,
                           -0.5f, -0.5f, 0.0f,
                           0.5f, -0.5f, 0.0f};

   	glClear(GL_COLOR_BUFFER_BIT);
   	glUseProgram(_program);

   	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
   	glEnableVertexAttribArray(0);

   	glDrawArrays (GL_TRIANGLES, 0, 3);

	glFlush();
}

static void 
cb_reshape(int width, int height) {
	logv("cb_reshape: width:%d, height:%d\n", width, height);
	glViewport (0, 0, width, height);
}

int
main(int argc, char *argv[]) {
	glutInit(&argc, argv);
	glutInitWindowSize(800, 400);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowPosition(0, 0);

	glutCreateWindow("OpenGL ES Title");

	if (init() == GL_FALSE)
		return 0;

	glClearColor(0, 0, 0, 1.f);

	glutDisplayFunc(cb_display);
	glutReshapeFunc(cb_reshape);
	glutMainLoop();

	glDeleteProgram(_program);
	return 0;
}

编译的话下载 glew 本身编译,freeglut 的话去官网有别人编译好的 mingw32 的连接,直接用就行了。makefile 以下。oop

hello_triangle:
	gcc chapter2/$@/$@.c -o bin/$@ -g -lfreeglut -lglew32.dll -lopengl32
clean:
	rm bin/*.exe

PS:如果发如今笔记本上不能运行,记得把显卡设置成使用独立显卡,如今的好多笔记本都是双显卡,默认用的集显,改为默认用独显。学习

问题:ui

  • glCompileShader 函数编译 shader 时是如何支持 opengles 的 shader 语法的,毕竟这是 PC 上用的 GPU 。
相关文章
相关标签/搜索