画一个四方形
我们在android,ios,win32上画这么个四方形。
ios 上没图。
来看代码,首先是android
package com.cloudgame.org;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView.Renderer;
public class GameRenderer implements Renderer {
@Override
public void onDrawFrame(GL10 arg0) {
// TODO Auto-generated method stub
//GLES20.glClearColor(1, 0, 0, 0);
// 清除屏幕和深度缓存
//GLES20.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
drawQuad();
}
@Override
public void onSurfaceChanged(GL10 arg0, int arg1, int arg2) {
// TODO Auto-generated method stub
GLES20.glViewport(0, 0, arg1, arg2);
}
@Override
public void onSurfaceCreated(GL10 arg0, EGLConfig arg1) {
// TODO Auto-generated method stub
setupQuad();
}
private native void setupQuad();
private native void drawQuad();
static {
System.loadLibrary("cloudGameEngine");
}
}
以及android cpp里
#include <jni.h>
#include <android/log.h>
#include <GLES2/gl2.h>
#include <string>
#include <vector>
#include <fstream>
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
#include <android/log.h>
#define LOG_TAG "ReadAssets"
#define LOG(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
GLuint LoadShaders()
{
//Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
//Read the Vertex Shader code from the file
std::string VertexShaderCode =
"attribute vec3 vertexPosition_modelspace; \n \
void main(){ \n \
gl_Position.xyz = vertexPosition_modelspace;\n \
gl_Position.w = 1.0;\n \
}";
//Read the Fragment Shader code from the file
std::string FragmentShaderCode =
"void main(){ \n \
gl_FragColor = vec4(1,0,0,1);\n \
}";
GLint Result = GL_FALSE;
int InfoLogLength;
//compile Vertex Shader
LOG("Compiling shader : n");
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL);
glCompileShader(VertexShaderID);
// Check vertex Shader
LOG("Compiling shader : n");
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> VerTexShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL,
&VerTexShaderErrorMessage[0]);
LOG( "%s\n", &VerTexShaderErrorMessage[0]);
//compile Fragment Shader
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL);
glCompileShader(FragmentShaderID);
// Check vertex Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> FragmentShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL,
&FragmentShaderErrorMessage[0]);
LOG("%s\n", &FragmentShaderErrorMessage[0]);
//Link the program
fprintf(stdout, "Linking programn");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
//Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> ProgramErrorMessage(InfoLogLength);
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL,
&ProgramErrorMessage[0]);
LOG( "%s\n", &ProgramErrorMessage[0]);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}
extern "C"
{
void Java_com_cloudgame_org_GameRenderer_setupQuad(JNIEnv *env, jobject thiz)
{
static const GLfloat g_vertex_buffer_data[] = {
-0.5f,0.5f,0.0f,
-0.5f,-0.5f,0.0f,
0.5f,0.5f,0.0f,
0.5f,-0.5f,0.0f,
};
//This will identify our vertex buffer
GLuint vertexbuffer;
//Generate 1 buffer,put the resulting identifier in vertexbuffer
glGenBuffers(1,&vertexbuffer);
//The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer);
//Give our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER,sizeof(g_vertex_buffer_data),g_vertex_buffer_data,GL_STATIC_DRAW);
GLuint programID = LoadShaders();
glUseProgram(programID);
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
}
void Java_com_cloudgame_org_GameRenderer_drawQuad(JNIEnv *env, jobject thiz)
{
// 清除屏幕和深度缓存
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*) 0 // array buffer offset
);
glDrawArrays(GL_TRIANGLE_STRIP,0,4); // Starting from vertex 0; 3 vertices total -> 1 triangle
glDisableVertexAttribArray(0);
}
}
接下来是win32代码
#include "stdafx.h"
#include <stdio.h>
#include "vector"
#include "string"
#include <fstream>
#include "glew.h"
#include <glfw3.h>
#define LOG(...) printf(__VA_ARGS__)
GLuint LoadShaders()
{
//Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
//Read the Vertex Shader code from the file
std::string VertexShaderCode =
"attribute vec3 vertexPosition_modelspace; \n \
void main(){ \n \
gl_Position.xyz = vertexPosition_modelspace;\n \
gl_Position.w = 1.0;\n \
}";
//Read the Fragment Shader code from the file
std::string FragmentShaderCode =
"void main(){ \n \
gl_FragColor = vec4(1,0,0,1);\n \
}";
GLint Result = GL_FALSE;
int InfoLogLength;
//compile Vertex Shader
LOG("Compiling shader : n");
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID,1,&VertexSourcePointer,NULL);
glCompileShader(VertexShaderID);
// Check vertex Shader
glGetShaderiv(VertexShaderID,GL_COMPILE_STATUS,&Result);
glGetShaderiv(VertexShaderID,GL_INFO_LOG_LENGTH,&InfoLogLength);
std::vector<char> VerTexShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(VertexShaderID,InfoLogLength,NULL,&VerTexShaderErrorMessage[0]);
LOG("%s\n",&VerTexShaderErrorMessage[0]);
//compile Fragment Shader
LOG("Compiling shader : n");
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID,1,&FragmentSourcePointer,NULL);
glCompileShader(FragmentShaderID);
// Check vertex Shader
glGetShaderiv(FragmentShaderID,GL_COMPILE_STATUS,&Result);
glGetShaderiv(FragmentShaderID,GL_INFO_LOG_LENGTH,&InfoLogLength);
std::vector<char> FragmentShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(FragmentShaderID,InfoLogLength,NULL,&FragmentShaderErrorMessage[0]);
LOG("%s\n",&FragmentShaderErrorMessage[0]);
//Link the program
LOG("Linking programn");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID,VertexShaderID);
glAttachShader(ProgramID,FragmentShaderID);
glLinkProgram(ProgramID);
//Check the program
glGetProgramiv(ProgramID,GL_LINK_STATUS,&Result);
glGetProgramiv(ProgramID,GL_INFO_LOG_LENGTH,&InfoLogLength);
std::vector<char> ProgramErrorMessage(InfoLogLength);
glGetProgramInfoLog(ProgramID,InfoLogLength,NULL,&ProgramErrorMessage[0]);
LOG("%s\n",&ProgramErrorMessage[0]);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}
void setupQuad()
{
// An array of 3 vectors which represents 3 vertices
static const GLfloat g_vertex_buffer_data[] = {
-0.5f,0.5f,0.0f,
-0.5f,-0.5f,0.0f,
0.5f,0.5f,0.0f,
0.5f,-0.5f,0.0f,
};
//This will identify our vertex buffer
GLuint vertexbuffer;
//Generate 1 buffer,put the resulting identifier in vertexbuffer
glGenBuffers(1,&vertexbuffer);
//The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer);
//Give our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER,sizeof(g_vertex_buffer_data),g_vertex_buffer_data,GL_STATIC_DRAW);
GLuint programID = LoadShaders();
glUseProgram(programID);
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
}
void drawQuad()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
glDrawArrays(GL_TRIANGLE_STRIP,0,4);// Starting from vertex 0; 3 vertices total -> 1 triangle
glDisableVertexAttribArray(0);
}
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(320, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
// Needed in core profile
if( glewInit() != GLEW_OK)
{
glfwTerminate();
return -1;
}
setupQuad();
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
drawQuad();
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return true;
}
再来ios
#include "vector"
#include "string"
#include <fstream>
#define LOG(...) printf(__VA_ARGS__)
GLuint LoadShaders()
{
//Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
//Read the Vertex Shader code from the file
std::string VertexShaderCode =
"attribute vec3 vertexPosition_modelspace; \n \
void main(){ \n \
gl_Position.xyz = vertexPosition_modelspace;\n \
gl_Position.w = 1.0;\n \
}";
//Read the Fragment Shader code from the file
std::string FragmentShaderCode =
"void main(){ \n \
gl_FragColor = vec4(1,0,0,1);\n \
}";
GLint Result = GL_FALSE;
int InfoLogLength;
//compile Vertex Shader
LOG("Compiling shader : n");
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID,1,&VertexSourcePointer,NULL);
glCompileShader(VertexShaderID);
// Check vertex Shader
glGetShaderiv(VertexShaderID,GL_COMPILE_STATUS,&Result);
glGetShaderiv(VertexShaderID,GL_INFO_LOG_LENGTH,&InfoLogLength);
std::vector<char> VerTexShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(VertexShaderID,InfoLogLength,NULL,&VerTexShaderErrorMessage[0]);
LOG("%s\n",&VerTexShaderErrorMessage[0]);
//compile Fragment Shader
LOG("Compiling shader : n");
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID,1,&FragmentSourcePointer,NULL);
glCompileShader(FragmentShaderID);
// Check vertex Shader
glGetShaderiv(FragmentShaderID,GL_COMPILE_STATUS,&Result);
glGetShaderiv(FragmentShaderID,GL_INFO_LOG_LENGTH,&InfoLogLength);
std::vector<char> FragmentShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(FragmentShaderID,InfoLogLength,NULL,&FragmentShaderErrorMessage[0]);
LOG("%s\n",&FragmentShaderErrorMessage[0]);
//Link the program
LOG("Linking programn");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID,VertexShaderID);
glAttachShader(ProgramID,FragmentShaderID);
glLinkProgram(ProgramID);
//Check the program
glGetProgramiv(ProgramID,GL_LINK_STATUS,&Result);
glGetProgramiv(ProgramID,GL_INFO_LOG_LENGTH,&InfoLogLength);
std::vector<char> ProgramErrorMessage(InfoLogLength);
glGetProgramInfoLog(ProgramID,InfoLogLength,NULL,&ProgramErrorMessage[0]);
LOG("%s\n",&ProgramErrorMessage[0]);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}
void setupQuad()
{
// An array of 3 vectors which represents 3 vertices
static const GLfloat g_vertex_buffer_data[] = {
-0.5f,0.5f,0.0f,
-0.5f,-0.5f,0.0f,
0.5f,0.5f,0.0f,
0.5f,-0.5f,0.0f,
};
//This will identify our vertex buffer
GLuint vertexbuffer;
//Generate 1 buffer,put the resulting identifier in vertexbuffer
glGenBuffers(1,&vertexbuffer);
//The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer);
//Give our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER,sizeof(g_vertex_buffer_data),g_vertex_buffer_data,GL_STATIC_DRAW);
GLuint programID = LoadShaders();
glUseProgram(programID);
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
}
void drawQuad()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
glDrawArrays(GL_TRIANGLE_STRIP,0,4);// Starting from vertex 0; 3 vertices total -> 1 triangle
glDisableVertexAttribArray(0);
}
#import "cloudViewController.h"
@interface cloudViewController () {
GLuint _program;
}
@property (strong, nonatomic) EAGLContext *context;
- (void)setupGL;
- (void)tearDownGL;
@end
@implementation cloudViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
if (!self.context) {
NSLog(@"Failed to create ES context");
}
GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
[self setupGL];
}
- (void)dealloc
{
[self tearDownGL];
if ([EAGLContext currentContext] == self.context) {
[EAGLContext setCurrentContext:nil];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
if ([self isViewLoaded] && ([[self view] window] == nil)) {
self.view = nil;
[self tearDownGL];
if ([EAGLContext currentContext] == self.context) {
[EAGLContext setCurrentContext:nil];
}
self.context = nil;
}
// Dispose of any resources that can be recreated.
}
- (void)setupGL
{
[EAGLContext setCurrentContext:self.context];
setupQuad();
}
- (void)tearDownGL
{ [EAGLContext setCurrentContext:self.context];
// if (_program) {
// glDeleteProgram(_program);
// _program = 0;
// }
}
#pragma mark - GLKView and GLKViewController delegate methods
- (void)update
{
}
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
drawQuad();
}
#pragma mark - OpenGL ES 2 shader compilation
@end
我们会发现与图像显示相关的函数是一样的。LoadShaders(),setupQuad(),drawQuad()。我们把它们封装成类,进行拓展,也就是引擎了。