I have a fully functional app using this videoRenderer
internal class VideoRenderer {
private var pos_coord_box :Int32 = 0
private var pos_tex_box:Int32 = 0
private var pos_trans_box:Int32 = 0
private var pos_proj_box:Int32 = 0
private var vbo_coord_box: GLuint = 0
private var vbo_tex_box: GLuint = 0
private var vbo_face_box: GLuint = 0
private var program_box: GLuint = 0
private var texture_id: GLuint = 0
private var vertShader: GLuint = 0
private var fragShader: GLuint = 0
init(){
let box_video_vert=""
+ "uniform mat4 trans; \n"
+ "uniform mat4 proj; \n"
+ "attribute vec4 coord; \n"
+ "attribute vec2 texcoord; \n"
+ "varying vec2 vtexcoord; \n\n"
+ "void main(void)\n"
+ "{\n"
+ " vtexcoord = texcoord;\n"
+ " gl_Position = proj*trans*coord;\n"
+ "}\n"
+ "\n"
let box_video_frag=""
+ "#ifdef GL_ES \n"
+ "precision highp float; \n"
+ "#endif \n"
+ "varying vec2 vtexcoord; \n"
+ "uniform sampler2D texture; \n\n"
+ "void main(void) \n"
+ "{"
+ "\n gl_FragColor = texture2D(texture, vtexcoord);\n"
+ "}"
+ "\n\n"
program_box = glCreateProgram()
/**Initialize verticle shader **/
vertShader = glCreateShader(GLenum(GL_VERTEX_SHADER))
box_video_vert.utf8CString.withUnsafeBufferPointer { p in
var s = p.baseAddress
glShaderSource(vertShader, 1, &s, nil)
}
glCompileShader(vertShader);
/**Initialize fragment shader **/
fragShader = glCreateShader(GLenum(GL_FRAGMENT_SHADER))
box_video_frag.utf8CString.withUnsafeBufferPointer { p in
var s = p.baseAddress
glShaderSource(fragShader, 1, &s, nil)
}
glCompileShader(fragShader)
/**Attach both shaders to program **/
glAttachShader(program_box, vertShader);
glAttachShader(program_box, fragShader);
glLinkProgram(program_box);
glUseProgram(program_box);
glDetachShader(program_box, vertShader)
glDeleteShader(vertShader)
glDetachShader(program_box, fragShader)
glDeleteShader(fragShader)
pos_coord_box = glGetAttribLocation(program_box, "coord");
pos_tex_box = glGetAttribLocation(program_box, "texcoord");
pos_trans_box = glGetUniformLocation(program_box, "trans");
pos_proj_box = glGetUniformLocation(program_box, "proj");
//Set the plane four corners
vbo_coord_box = 0
glGenBuffers(1, &vbo_coord_box);
glBindBuffer(GLenum(GL_ARRAY_BUFFER), vbo_coord_box)
// let cube_vertices:[[GLfloat]] = [[(1.0 / 2), (1.0 / 2), 0.0], [(1.0 / 2), (-1.0 / 2), 0.0],[ (-1.0 / 2), (-1.0 / 2), 0.0],[ (-1.0 / 2), (1.0 / 2), 0.0]] //4x3
let cube_vertices:[GLfloat] = [1.0 / 2, 1.0 / 2, 0.0, 1.0 / 2, -1.0 / 2, 0.0, -1.0 / 2, -1.0 / 2, 0.0, -1.0 / 2, 1.0 / 2, 0.0] //4x3
cube_vertices.withUnsafeBytes { p in
glBufferData(GLenum(GL_ARRAY_BUFFER), p.count, p.baseAddress, GLenum(GL_DYNAMIC_DRAW))
}
//Set the plane four Side
vbo_tex_box = 0
glGenBuffers(1, &vbo_tex_box);
glBindBuffer(GLenum(GL_ARRAY_BUFFER), vbo_tex_box)
let cube_vertex_texs : [GLubyte] = [0, 0, 0, 1, 1, 1, 1, 0]
cube_vertex_texs.withUnsafeBytes { p in
glBufferData(GLenum(GL_ARRAY_BUFFER), p.count, p.baseAddress, GLenum(GL_STATIC_DRAW))
}
//Set the face
vbo_face_box = 0
glGenBuffers(1, &vbo_face_box);
glBindBuffer(GLenum(GL_ELEMENT_ARRAY_BUFFER), vbo_face_box);
let cube_faces : [GLushort] = [3, 2, 1, 0]
cube_faces.withUnsafeBytes { p in
glBufferData(GLenum(GL_ELEMENT_ARRAY_BUFFER), p.count, p.baseAddress, GLenum(GL_STATIC_DRAW))
}
//Create the texture
glUniform1i(glGetUniformLocation(program_box, "texture"), 0);
texture_id = 0
glGenTextures(1, &texture_id);
glBindTexture(GLenum(GL_TEXTURE_2D), texture_id);
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MIN_FILTER), GL_LINEAR);
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MAG_FILTER), GL_LINEAR);
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_S), GL_CLAMP_TO_EDGE);
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_T), GL_CLAMP_TO_EDGE);
}
public func render(_ projectionMatrix:Matrix44F, _ cameraview:Matrix44F, _ size:Vec2F)
{
let (size0, size1) = size.data
//Adjust the four corners
glBindBuffer(GLenum(GL_ARRAY_BUFFER), vbo_coord_box)
let cube_vertices:[GLfloat] = [size0 / 2, size1 / 2, 0.0, size0 / 2, -size1 / 2, 0.0, -size0 / 2, -size1 / 2, 0.0, -size0 / 2, size1 / 2, 0.0]
cube_vertices.withUnsafeBytes { p in
glBufferData(GLenum(GL_ARRAY_BUFFER), p.count, p.baseAddress, GLenum(GL_DYNAMIC_DRAW))
}
glEnable(GLenum(GL_BLEND));
glBlendFunc(GLenum(GL_SRC_ALPHA), GLenum(GL_ONE_MINUS_SRC_ALPHA));
glEnable(GLenum(GL_DEPTH_TEST));
glUseProgram(program_box);
glBindBuffer(GLenum(GL_ARRAY_BUFFER), vbo_coord_box);
glEnableVertexAttribArray(GLuint(pos_coord_box));
glVertexAttribPointer(GLuint(pos_coord_box), 3, GLenum(GL_FLOAT), GLboolean(GL_FALSE), 0, nil);
glBindBuffer(GLenum(GL_ARRAY_BUFFER), vbo_tex_box);
glEnableVertexAttribArray(GLuint(pos_tex_box));
glVertexAttribPointer(GLuint(pos_tex_box), 2, GLenum(GL_UNSIGNED_BYTE), GLboolean(GL_FALSE), 0, nil);
var cameraview_data = cameraview.data
var projectionMatrix_data = projectionMatrix.data
withUnsafePointer(to: &cameraview_data) { p in
glUniformMatrix4fv(pos_trans_box, 1, GLboolean(GL_FALSE), UnsafePointer<GLfloat>(OpaquePointer(p)))
}
withUnsafePointer(to: &projectionMatrix_data) { p in
glUniformMatrix4fv(pos_proj_box, 1, GLboolean(GL_FALSE), UnsafePointer<GLfloat>(OpaquePointer(p)))
}
glBindBuffer(GLenum(GL_ELEMENT_ARRAY_BUFFER), vbo_face_box);
glActiveTexture(GLenum(GL_TEXTURE0));
glBindTexture(GLenum(GL_TEXTURE_2D), texture_id);
glDrawElements(GLenum(GL_TRIANGLE_FAN), 4, GLenum(GL_UNSIGNED_SHORT), nil)
glBindTexture(GLenum(GL_TEXTURE_2D), 0);
glFlush()
}
public func texid()->GLuint{
return texture_id
}
public func dispose(){
glDeleteProgram(program_box)
}
}