用 glew 来学习 opengles

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

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

之所以会选择 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 如下。

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

PS:若是发现在笔记本上不能运行,记得把显卡设置成使用独立显卡,现在的好多笔记本都是双显卡,默认用的集显,改成默认用独显。

问题:

  • glCompileShader 函数编译 shader 时是如何支持 opengles 的 shader 语法的,毕竟这是 PC 上用的 GPU 。

转载于:https://my.oschina.net/iirecord/blog/685719

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值