OpenGLES系列demo之(一):绘制三角形

        在上一篇文章 OpenGLES系列demo之框架简介 (后文简称“框架文章”)中,我们先介绍了框架,本文基于这个框架上,简述使用openGL ES绘制一个三角形的大致步骤。

一、绘制三角形的步骤

        绘制三角形的一般步骤如下:

  1. 创建 OpenGLES 环境(可以借助于 GLSurfaceView 创建的上下文对象);
  2. 编译并链接着色器程序;
  3. 指定着色器程序,为着色器程序中的变量赋值;
  4. 绘制。

二、创建OpenGLES环境

        这个创建在上一篇框架文章中搭建的框架基本上已经实现了openGLES环境,这里我们再简单过一下。

        1、简单自定义GLSurfackView。-- 参考“框架文章”中的MyGLSurfaceView;

        2、自定义Render实现GLSurfaceView.Renderer接口。 -- 参考“框架文章”中的MyGLRender;

        以上两步基本就创建好了openGLES环境,

        3、由于我们在c++层完成绘制,因此还需要与jni的一些接口调用。 -- 参考“框架文章”中的MyNativeRender等;

三、编译链接着色器程序,实现绘制类

        以下部分我们是在c++层去操作,实现绘制。

1、编译和链接着色器程序的类

        在我们的“框架文章”中,已经讲到将编译和绘制着色器相关的东西,提出到一个工具类GLUtils,这个类是通用的,实现编译和链接着色器程序等功能。这里不再赘述,看参考“框架”文章。

2、三角形的绘制实现类

        这个便是本文的重点,在框架的基础上,每个demo最重要的区别就是这里。在这个三角形的绘制实现类TriangleSample中,我们会实现三角形的绘制。包括它的顶点着色器等等的定义。

        三角形的顶点着色器脚本:

#version 300 es                          
layout(location = 0) in vec4 vPosition;  
void main()                              
{                                        
   gl_Position = vPosition;              
}                                        

        片元着色器脚本:

#version 300 es                              
precision mediump float;                     
out vec4 fragColor;                          
void main()                                  
{                                            
   fragColor = vec4 ( 0.0, 0.0, 1.0, 1.0 );  //填充三角形区域为蓝色
}                                            

        这两个脚本我们定义到字符串数组后,在绘制类的Init初始化函数中调用GLUtils工具类的创建程序进行相关绑定,如下:

void TriangleSample::Init()
{
	if(m_ProgramObj != 0)
		return;
	char vShaderStr[] =
			"#version 300 es                          \n"
			"layout(location = 0) in vec4 vPosition;  \n"
			"void main()                              \n"
			"{                                        \n"
			"   gl_Position = vPosition;              \n"
			"}                                        \n";

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

	m_ProgramObj = GLUtils::CreateProgram(vShaderStr, fShaderStr, m_VertexShader, m_FragmentShader);

}

        先来看下opengles 坐标系中三角形顶点坐标:

        接下来在Draw函数中指定着色器程序,为着色器程序中的变量赋值,传入顶点坐标信息,然后绘制三角形。如下:

void TriangleSample::Draw(int screenW, int screenH)
{
	LOGCATE("TriangleSample::Draw");
	GLfloat vVertices[] = {
			0.0f,  0.5f, 0.0f,
			-0.5f, -0.5f, 0.0f,
			0.5f, -0.5f, 0.0f,
	};

	if(m_ProgramObj == 0)
		return;

	glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClearColor(1.0, 1.0, 1.0, 1.0);

	// Use the program object
	glUseProgram (m_ProgramObj);

	// Load the vertex data
	glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, vVertices );
	glEnableVertexAttribArray (0);

	glDrawArrays (GL_TRIANGLES, 0, 3);
	glUseProgram (GL_NONE);

}

        三角形的实现绘制类TriangleSample中最重要就是这两个函数,初始化和绘制。

        它们的调用是在MyGLRenderContext类中调用,并提高给JNI,最终到java层去调用。

MyGLRenderContext::MyGLRenderContext()
{
	m_pCurSample = new TriangleSample();
	m_pBeforeSample = nullptr;

}

MyGLRenderContext::~MyGLRenderContext()
{
	if (m_pCurSample)
	{
		delete m_pCurSample;
		m_pCurSample = nullptr;
	}

	if (m_pBeforeSample)
	{
		delete m_pBeforeSample;
		m_pBeforeSample = nullptr;
	}

}

void MyGLRenderContext::OnSurfaceCreated()
{
	LOGCATE("MyGLRenderContext::OnSurfaceCreated");
	glClearColor(1.0f,1.0f,1.0f, 1.0f);
}

void MyGLRenderContext::OnSurfaceChanged(int width, int height)
{
	LOGCATE("MyGLRenderContext::OnSurfaceChanged [w, h] = [%d, %d]", width, height);
	glViewport(0, 0, width, height);
	m_ScreenW = width;
	m_ScreenH = height;
}

void MyGLRenderContext::OnDrawFrame()
{
	LOGCATE("MyGLRenderContext::OnDrawFrame");
	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

	if (m_pBeforeSample)
	{
		m_pBeforeSample->Destroy();
		delete m_pBeforeSample;
		m_pBeforeSample = nullptr;
	}

	if (m_pCurSample)
	{
		m_pCurSample->Init();
		m_pCurSample->Draw(m_ScreenW, m_ScreenH);
	}
}

        到这里demo基本就做完了。

四、运行demo

        运行一下demo,可以看到效果如下:

         该demo已放到github上,有需要的可以下载看看:

https://github.com/weekend-y/openGL_Android_demo/tree/master/BaseDemo/OpenGL_Triangle

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用NDK和OpenGL ES 3.0来绘制一个三角形可以分为以下几个步骤: 1. 首先,创建一个安卓项目,并配置NDK环境。 2. 在项目的jni目录下,创建一个C/C++源文件triangle.c。 3. 在triangle.c文件中,引入相关的头文件,包括<jni.h>和<GLES3/gl3.h>。 4. 在triangle.c文件中,实现一个JNI函数,用于绘制三角形。函数的参数为Surface对象。 5. 在JNI函数中,通过EGL和GLES初始化OpenGL环境,并创建一个EGLSurface用于后续的绘制操作。 6. 在JNI函数中,创建一个顶点数组和顶点缓冲,并将顶点数据存入顶点缓冲。 7. 在JNI函数中,编写着色器代码,包括顶点着色器和片段着色器,并编译和链接它们。 8. 在JNI函数中,通过glClearColor()函数设置清空屏幕时的颜色。 9. 在JNI函数中,通过glClear()函数清空屏幕,并启用深度测试。 10. 在JNI函数中,通过glViewport()函数设置视口大小。 11. 在JNI函数中,通过glUseProgram()函数使用着色器程序。 12. 在JNI函数中,通过glVertexAttribPointer()函数设置顶点数据的属性,并启用顶点属性。 13. 在JNI函数中,通过glDrawArrays()函数绘制三角形。 14. 在JNI函数中,通过eglSwapBuffers()函数交换绘制的缓冲区。 15. 在JNI函数中,清理OpenGL环境,并释放资源。 16. 在Java层的MainActivity中,通过JNI调用C/C++函数进行绘制。 以上是绘制一个三角形的大致步骤。具体的细节和代码实现可以参考相关的OpenGL ES 3.0和NDK的文档和示例代码。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值