Skip to content

Instantly share code, notes, and snippets.

@denisdemaisbr
Forked from knighthedspi/Android.mk
Created March 4, 2024 04:09
Show Gist options
  • Save denisdemaisbr/74307c13c8ebd0c21ffa5487ad77d49d to your computer and use it in GitHub Desktop.
Save denisdemaisbr/74307c13c8ebd0c21ffa5487ad77d49d to your computer and use it in GitHub Desktop.
Render to screen using FrameBuffer using OpenGL ES 2.0
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := FriengerScreenRecord
LOCAL_SRC_FILES := Log.cpp CustomFrameBuffer.cpp CustomFrameTexture.cpp FriengerScreenRecord.cpp
LOCAL_CFLAGS := -Werror -std=gnu++11
LOCAL_LDLIBS := -llog -lGLESv2
include $(BUILD_SHARED_LIBRARY)
#include <CustomFrameBuffer.h>
void CustomFrameBuffer::setResolution(int width, int height) {
printLog(DEBUG, "set resolution to FrameBuffer: width=%d, height=%d", width, height);
if (this->framebuffer != -1) {
release();
}
GLuint *glValues;
glValues = (GLuint *) malloc(sizeof(GLuint));
glGenTextures(1, glValues);
checkGlError("glGenTextures");
this->offScreenTexture = *glValues;
free(glValues);
glBindTexture(GL_TEXTURE_2D, this->offScreenTexture);
checkGlError("glBindTexture");
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
checkGlError("glTexImage2D");
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// get previous gl state
GLint *glState;
glState = (GLint *) malloc(sizeof(GLint));
glGetIntegerv(GL_FRAMEBUFFER_BINDING, glState);
checkGlError("get current FrameBuffer binding %d", glState);
this->defaultFBO = *glState;
free(glState);
glValues = (GLuint *) malloc(sizeof(GLuint));
glGetIntegerv(GL_RENDERBUFFER_BINDING, glState);
checkGlError("get current RenderBuffer binding %d", glState);
this->defaultRenderBuffer = *glState;
free(glState);
glValues = (GLuint *) malloc(sizeof(GLuint));
glGenFramebuffers(1, glValues);
checkGlError("glGenFramebuffers");
this->framebuffer = *glValues;
free(glValues);
glBindFramebuffer(GL_FRAMEBUFFER, this->framebuffer);
checkGlError("glBindFramebuffer");
glValues = (GLuint *) malloc(sizeof(GLuint));
glGenRenderbuffers(1, glValues);
checkGlError("glGenRenderbuffers");
this->depthBuffer = *glValues;
free(glValues);
glBindRenderbuffer(GL_RENDERBUFFER, this->depthBuffer);
checkGlError("glBindRenderbuffer");
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
checkGlError("glRenderbufferStorage");
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, this->depthBuffer);
checkGlError("glFramebufferRenderbuffer");
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
this->offScreenTexture, 0);
checkGlError("glFramebufferTexture2D");
int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
checkGlError("glCheckFramebufferStatus");
if (status != GL_FRAMEBUFFER_COMPLETE) {
printLog(ERROR, "failed when create frame buffer");
}
// restore 2 current Unity FBO, renderbuffer
glBindFramebuffer(GL_FRAMEBUFFER, this->defaultFBO);
checkGlError("glBindFramebuffer to default value:%d", this->defaultFBO);
glBindRenderbuffer(GL_RENDERBUFFER, this->defaultRenderBuffer);
checkGlError("glBindRenderbuffer to default value:%d", this->defaultRenderBuffer);
}
int CustomFrameBuffer::getOffScreenTexture() {
return this->offScreenTexture;
}
void CustomFrameBuffer::bind() {
glViewport(0, 0, this->width, this->height);
// get default Unity FBO
GLint *temp;
temp =(GLint *)malloc(sizeof(GLint));
glGetIntegerv(GL_FRAMEBUFFER_BINDING, temp);
checkGlError("get default Unity FBO");
this->defaultFBO = *temp;
free(temp);
temp =(GLint *)malloc(sizeof(GLint));
glGetIntegerv(GL_RENDERBUFFER_BINDING, temp);
checkGlError("get default render buffer");
this->defaultRenderBuffer = *temp;
free(temp);
glBindFramebuffer(GL_FRAMEBUFFER, this->framebuffer);
checkGlError("bind custom FBO:%d", this->framebuffer);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
checkGlError("clear buffer");
}
void CustomFrameBuffer::unbind() {
// restore 2 current Unity FBO, renderbuffer
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
checkGlError("glBindFramebuffer(default:%d)", defaultFBO);
glBindRenderbuffer(GL_RENDERBUFFER, defaultRenderBuffer);
checkGlError("glBindRenderbuffer (default:%d)", defaultRenderBuffer);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
checkGlError("clear buffer");
}
void CustomFrameBuffer::release() {
GLuint *glValues ;
if (this->offScreenTexture > 0) {
glValues = (GLuint *) malloc(sizeof(GLuint));
*glValues = this->offScreenTexture;
glDeleteBuffers(1, glValues);
this->offScreenTexture = -1;
free(glValues);
}
if (this->framebuffer > 0) {
glValues = (GLuint *) malloc(sizeof(GLuint));
*glValues = this->framebuffer;
glDeleteFramebuffers(1, glValues);
this->framebuffer = -1;
free(glValues);
}
if (this->depthBuffer > 0) {
glValues = (GLuint *) malloc(sizeof(GLuint));
*glValues = this->depthBuffer;
glDeleteRenderbuffers(1, glValues);
this->depthBuffer = -1;
free(glValues);
}
}
#ifndef CUSTOMFRAMEBUFFER_H_
#define CUSTOMFRAMEBUFFER_H_
#include <Log.h>
class CustomFrameBuffer {
// attribute
private:
int width;
int height;
int framebuffer;
int offScreenTexture;
int depthBuffer;
int defaultFBO;
int defaultRenderBuffer;
// method
public:
static CustomFrameBuffer& getInstance() {
static CustomFrameBuffer instance;
return instance;
}
void setResolution(int width, int height);
int getOffScreenTexture();
void release();
void bind();
void unbind();
private:
CustomFrameBuffer() {
this->defaultFBO = -1;
this->defaultRenderBuffer = -1;
this->depthBuffer = -1;
this->width = width;
this->height = height;
this->framebuffer = -1;
this->offScreenTexture = -1;
};
CustomFrameBuffer(CustomFrameBuffer const &);
void operator=(CustomFrameBuffer const&);
};
#endif
#include <CustomFrameTexture.h>
const char CustomFrameTexture::VERTEXT_SHADER_EXT[] = "\n"
"attribute vec4 a_position;\n"
"uniform mat4 u_matrix;\n"
"\n\n"
"#ifdef GL_ES\nvarying mediump vec2 v_texCoord;\n"
"#else\nvarying vec2 v_texCoord;\n"
"#endif\n\n"
"void main()\n{\n"
" gl_Position = u_matrix * a_position;\n "
"v_texCoord =\n"
" 0.5*(a_position.xy + vec2(1.0, 1.0));\n}\n";
const char CustomFrameTexture::FRAGMENT_SHADER_EXT[] = "\n"
"#ifdef GL_ES\nprecision lowp float;\n"
"#endif\n\n"
"varying vec2 v_texCoord;\n"
"uniform sampler2D u_texture;\n"
"\nvoid main()\n"
"{\n gl_FragColor = vec4( texture2D(u_texture,\n"
" v_texCoord).xyz, 1.0 );\n}\n";
const float CustomFrameTexture::FLOAT_QUAD_COORDINATES[8] = { -1.0F, -1.0F, 1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 1.0F };
const int CustomFrameTexture::LOCAL_BYTE[4] = { 0, 1, 2, 3 };
const float CustomFrameTexture::UNIFORM_DATA[16] = { 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F };
void CustomFrameTexture::initCustomFrameTexture() {
printLog(DEBUG, "Initialize custom frame texture !");
this->currProgram = glCreateProgram();
checkGlError("create program %d", this->currProgram);
this->vertexShader = initShader(GL_VERTEX_SHADER, CustomFrameTexture::VERTEXT_SHADER_EXT);
if (this->vertexShader == 0) {
printLog(ERROR, "error when create vertex shader with source %s!!!", CustomFrameTexture::VERTEXT_SHADER_EXT);
return;
}
this->fragmentShader = initShader(GL_FRAGMENT_SHADER, CustomFrameTexture::FRAGMENT_SHADER_EXT);
if (this->fragmentShader == 0) {
printLog(ERROR, "error when create fragment shader witg source %s !!!", CustomFrameTexture::FRAGMENT_SHADER_EXT);
return;
}
// attach shader
glAttachShader(this->currProgram, this->vertexShader);
checkGlError("attach vertex shader");
glAttachShader(this->currProgram, this->fragmentShader);
checkGlError("attach fragment shader");
// create temporary array to use 4 save return value
GLint *tempArr;
tempArr = (GLint *) malloc(sizeof(GLint));
// get max attributes of vertex
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, tempArr);
this->maxVertexAttribs = *tempArr - 1;
// bind attributes location to last index of vertex attribute array
glBindAttribLocation(this->currProgram, this->maxVertexAttribs, "a_position");
checkGlError("bind attribute location");
// link program
glLinkProgram(this->currProgram);
checkGlError("link program " + currProgram);
// check shader link status of current program
getGlInfo(GL_LINK_STATUS);
// check validate status of current program
getGlInfo(GL_VALIDATE_STATUS);
// delete shader to reduce usage of memory
if (this->vertexShader != 0) {
glDeleteShader(this->vertexShader);
this->vertexShader = 0;
}
if (this->fragmentShader != 0) {
glDeleteShader(this->fragmentShader);
this->fragmentShader = 0;
}
// get previous state : openGL program, current binding array buffer, current binding element array buffer
free(tempArr);
tempArr = (GLint *) malloc(sizeof(GLint));
glGetIntegerv(GL_CURRENT_PROGRAM, tempArr);
int previousProgram = *tempArr;
free(tempArr);
tempArr = (GLint *) malloc(sizeof(GLint));
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, tempArr);
int previousArrBuffBinding = *tempArr;
free(tempArr);
tempArr = (GLint *) malloc(sizeof(GLint));
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, tempArr);
int previousElementArrBuffBinding = *tempArr;
free(tempArr);
// use our created program
glUseProgram(this->currProgram);
checkGlError("use current program %d", this->currProgram);
// get uniform location
this->textureLocation = glGetUniformLocation(this->currProgram, "u_texture");
checkGlError("get texture location %d", this->textureLocation);
this->matrixLocation = glGetUniformLocation(this->currProgram, "u_matrix");
checkGlError("get matrix location %d", this->matrixLocation);
// generate new array buffer, element array buffer then bind
GLuint *temp;
temp = (GLuint *) malloc(sizeof(GLuint));
glGenBuffers(1, temp);
this->arrBuff = *temp;
free(temp);
temp = (GLuint *) malloc(sizeof(GLuint));
glGenBuffers(1, temp);
this->elementArrBuff = *temp;
free(temp);
glBindBuffer(GL_ARRAY_BUFFER, this->arrBuff);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 8, FLOAT_QUAD_COORDINATES, GL_STATIC_DRAW);
checkGlError("bind buffer data to array buffer %d", this->arrBuff);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->elementArrBuff);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * 4, LOCAL_BYTE, GL_STATIC_DRAW);
checkGlError("bind buffer data to element array buffer %d", this->elementArrBuff);
// restore previous state
glBindBuffer(GL_ARRAY_BUFFER, previousArrBuffBinding);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, previousElementArrBuffBinding);
glUseProgram(previousProgram);
}
GLuint CustomFrameTexture::initShader(GLenum type, const char* shaderTxt) {
GLint compiled;
if (shaderTxt == NULL){
printLog(ERROR,"null shader");
return 0;
}
int shader = glCreateShader(type);
checkGlError("create shader %d", shader);
// create shader then compile
glShaderSource(shader, 1, &shaderTxt, NULL);
checkGlError("attach shader source %s to shader %d", shaderTxt, shader);
glCompileShader(shader);
checkGlError("compile shader %d", shader);
// check compile status
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
GLint infoLen = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen > 1) {
char* infoLog = (char *) malloc(sizeof(char) * infoLen);
glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
printLog(ERROR, "Error compiling shader:\n%s\n", infoLog);
free(infoLog);
}
glDeleteShader(shader);
return 0;
}
return shader;
}
void CustomFrameTexture::draw2Screen(int textureId, int width, int height) {
/* get previous state : vertex attribute array enabled , current binding vertex attribute array, active texture,
* current 2d binding texture, current program, current binding element array buffer, current binding array buffer
*/
// temp array that used to save return value
GLint *tempArr ;
tempArr = (GLint *) malloc(sizeof(GLint));
glGetVertexAttribiv(this->maxVertexAttribs, GL_VERTEX_ATTRIB_ARRAY_ENABLED, tempArr);
int enableVertexAttribArray = *tempArr;
checkGlError("check vertex_attrib_enable: %d", enableVertexAttribArray);
free(tempArr);
tempArr = (GLint *) malloc(sizeof(GLint));
glGetVertexAttribiv(this->maxVertexAttribs, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, tempArr);
int bindingVertexAtrribArray = *tempArr;
checkGlError("get vertex attributes array buffer binding %d", bindingVertexAtrribArray);
free(tempArr);
tempArr = (GLint *) malloc(sizeof(GLint));
glGetIntegerv(GL_ACTIVE_TEXTURE, tempArr);
int activeTexture = *tempArr;
checkGlError("get active texture %d", activeTexture);
free(tempArr);
tempArr = (GLint *) malloc(sizeof(GLint));
glGetIntegerv(GL_TEXTURE_BINDING_2D, tempArr);
int binding2DTexture = *tempArr;
checkGlError("get texture binding 2D %d", binding2DTexture);
free(tempArr);
tempArr = (GLint *) malloc(sizeof(GLint));
glGetIntegerv(GL_CURRENT_PROGRAM, tempArr);
int previousProgram = *tempArr;
checkGlError("get current program %d", previousProgram);
free(tempArr);
tempArr = (GLint *) malloc(sizeof(GLint));
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, tempArr);
int arrayBufferBinding = *tempArr;
checkGlError("get array buffer binding %d", arrayBufferBinding);
free(tempArr);
tempArr = (GLint *) malloc(sizeof(GLint));
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, tempArr);
int elementArrayBufferBinding = *tempArr;
checkGlError("get element array binding %d", elementArrayBufferBinding);
free(tempArr);
// disable Blend, cull face, depth test if enabled
int enableBlend = glIsEnabled(GL_BLEND);
if (enableBlend)
glDisable(GL_BLEND);
int enableCullFace = glIsEnabled(GL_CULL_FACE);
if (enableCullFace)
glDisable(GL_CULL_FACE);
int depthTest = glIsEnabled(GL_DEPTH_TEST);
if (depthTest)
glDisable(GL_DEPTH_TEST);
// get depth func, change value to GL_LESS
tempArr = (GLint *) malloc(sizeof(GLint));
glGetIntegerv(GL_DEPTH_FUNC, tempArr);
int depthFunc = *tempArr;
if (depthFunc != GL_LESS)
glDepthFunc(GL_LESS);
free(tempArr);
// set viewport
glViewport(0, 0, width, height);
// bind texture using textureId
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureId);
// save previous texture state : min filter, mag filter, wrapS, wrapT
tempArr = (GLint *) malloc(sizeof(GLint));
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, tempArr);
int textureMinFilter = *tempArr;
free(tempArr);
// set texture min filter to nearest
if (textureMinFilter != GL_NEAREST){
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
checkGlError("set texture parameter GL_TEXTURE_MIN_FILTER to GL_NEAREST");
}
tempArr = (GLint *) malloc(sizeof(GLint));
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, tempArr);
int textureMagFilter = *tempArr;
free(tempArr);
// set texture mag filter to nearest
if (textureMagFilter != GL_NEAREST){
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
checkGlError("set texture parameter GL_TEXTURE_MAG_FILTER to GL_NEAREST");
}
tempArr = (GLint *) malloc(sizeof(GLint));
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, tempArr);
int textureWrapS = *tempArr;
free(tempArr);
// set texture wrap S to clamp to edge
if (textureWrapS != GL_CLAMP_TO_EDGE){
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
checkGlError("set texture parameter GL_TEXTURE_WRAP_S to GL_CLAMP_TO_EDGE");
}
tempArr = (GLint *) malloc(sizeof(GLint));
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, tempArr);
int textureWrapT = *tempArr;
free(tempArr);
// set texture wrap T to clamp to edge
if (textureWrapT != GL_CLAMP_TO_EDGE){
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
checkGlError("set texture parameter GL_TEXTURE_WRAP_T to GL_CLAMP_TO_EDGE");
}
// use our created program
if(glIsProgram(this->currProgram) != GL_TRUE){
printLog(ERROR,"error using GL program: %d", this->currProgram);
}
glUseProgram(this->currProgram);
checkGlError("use program %d", this->currProgram);
// bind our created array buffer, element array buffer
glBindBuffer(GL_ARRAY_BUFFER, this->arrBuff);
checkGlError("bind array buffer ");
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->elementArrBuff);
checkGlError("bind element array buffer ");
// enable vertex attribute array with our created index
glEnableVertexAttribArray(this->maxVertexAttribs);
checkGlError("enable vertex attribute %d", this->maxVertexAttribs);
glVertexAttribPointer(this->maxVertexAttribs, 2, GL_FLOAT, false, 0, 0);
checkGlError("create a pointer 2 vertex attributes %d", this->maxVertexAttribs);
// modify uniform location matrix
glUniformMatrix4fv(this->matrixLocation, 0, false, this->UNIFORM_DATA);
checkGlError("uniform matrix ");
glUniform1i(this->textureLocation, 0);
checkGlError("uniform texture");
// draw quad
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
checkGlError("draw array with matrix location: %d "
"& texture location: %d & maxVertexAttribs: %d", this->matrixLocation, this->textureLocation, this->maxVertexAttribs);
// restore state
if (enableVertexAttribArray)
glEnableVertexAttribArray(this->maxVertexAttribs);
else
glDisableVertexAttribArray(this->maxVertexAttribs);
glBindBuffer(GL_ARRAY_BUFFER, bindingVertexAtrribArray);
glUseProgram(previousProgram);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBufferBinding);
glBindBuffer(GL_ARRAY_BUFFER, arrayBufferBinding);
if (activeTexture != GL_TEXTURE0)
glActiveTexture(activeTexture);
glBindTexture(GL_TEXTURE_2D, binding2DTexture);
if (enableBlend)
glEnable(GL_BLEND);
if (enableCullFace)
glEnable(GL_CULL_FACE);
if (depthTest)
glEnable(GL_DEPTH_TEST);
if (depthFunc != GL_LESS)
glDepthFunc(depthFunc);
}
void CustomFrameTexture::getGlInfo(GLenum type){
// check shader link status of current program
GLint status;
glGetProgramiv(this->currProgram, type, &status);
if (!status) {
GLint maxLength;
glGetProgramiv(this->currProgram, GL_INFO_LOG_LENGTH, &maxLength);
char* infoLog = (char *) malloc(sizeof(char) * maxLength);
glGetProgramInfoLog(this->currProgram, maxLength, NULL, infoLog);
printLog(ERROR, infoLog);
free(infoLog);
}
}
void CustomFrameTexture::release() {
if (this->currProgram > 0) {
glDeleteProgram(this->currProgram);
this->currProgram = 0;
}
GLuint *temp;
if (this->arrBuff != 0) {
temp = (GLuint*) malloc(sizeof(GLuint));
*temp = this->arrBuff;
glDeleteBuffers(1, temp);
free(temp);
}
if (this->elementArrBuff != 0) {
temp = (GLuint*) malloc(sizeof(GLuint));
*temp = this->elementArrBuff;
glDeleteBuffers(1, temp);
free(temp);
}
}
#ifndef CUSTOMFRAMETEXTURE_H
#define CUSTOMFRAMETEXTURE_H
#include <Log.h>
class CustomFrameTexture {
// attribute
private:
// vertext shader
static const char VERTEXT_SHADER_EXT[];
// fragment shader
static const char FRAGMENT_SHADER_EXT[];
// coordinates
static const float FLOAT_QUAD_COORDINATES[8];
// buffer data
static const int LOCAL_BYTE[4];
// uniform data
static const float UNIFORM_DATA[16];
int arrBuff;
int elementArrBuff;
int currProgram;
GLuint vertexShader;
GLuint fragmentShader;
int maxVertexAttribs;
int textureLocation;
int matrixLocation;
// method
public:
static CustomFrameTexture& getInstance(){
static CustomFrameTexture instance;
return instance;
}
void initCustomFrameTexture();
void draw2Screen(int textureId,int width, int height);
void release();
private:
CustomFrameTexture(){
this->arrBuff = -1;
this->elementArrBuff = -1;
this->currProgram = -1;
this->vertexShader = -1;
this->fragmentShader = -1;
this->maxVertexAttribs = -1;
this->textureLocation = -1;
this->matrixLocation = -1;
};
CustomFrameTexture(CustomFrameTexture const&);
void operator=(CustomFrameTexture const&);
GLuint initShader(GLenum type,const char* shaderTxt);
void getGlInfo(GLenum type);
};
#endif
#include <FriengerScreenRecord.h>
/*
* Class: jp_oot_screenrecorder_ScreenRecordNative
* Method: initGLContext
* Signature: (II)V
*/JNIEXPORT void JNICALL Java_jp_oot_screenrecorder_ScreenRecordNative_initGLContext(
JNIEnv * jEnv, jclass jClass, jint width, jint height) {
printLog(DEBUG, "Initialize GLContext with width=%d, height=%d", width, height);
CustomFrameBuffer::getInstance().setResolution(width, height);
CustomFrameTexture::getInstance().initCustomFrameTexture();
}
/*
* Class: jp_oot_screenrecorder_ScreenRecordNative
* Method: bindFrameBuffer
* Signature: ()V
*/JNIEXPORT void JNICALL Java_jp_oot_screenrecorder_ScreenRecordNative_bindFrameBuffer(
JNIEnv * jEnv, jclass jClass) {
printLog(DEBUG, "bind custom FrameBuffer");
CustomFrameBuffer::getInstance().bind();
}
/*
* Class: jp_oot_screenrecorder_ScreenRecordNative
* Method: unbindFrameBuffer
* Signature: ()V
*/JNIEXPORT void JNICALL Java_jp_oot_screenrecorder_ScreenRecordNative_unbindFrameBuffer(
JNIEnv * jEnv, jclass jClass) {
printLog(DEBUG, "unbind custom FrameBuffer");
CustomFrameBuffer::getInstance().unbind();
}
/*
* Class: jp_oot_screenrecorder_ScreenRecordNative
* Method: draw2Screen
* Signature: (III)V
*/JNIEXPORT void JNICALL Java_jp_oot_screenrecorder_ScreenRecordNative_draw2Screen(
JNIEnv * jEnv, jclass jClass, jint width, jint height) {
GLint textureId = CustomFrameBuffer::getInstance().getOffScreenTexture();
printLog(DEBUG, "draw texture %d to screen(width = %d , height = %d)", textureId, width, height);
CustomFrameTexture::getInstance().draw2Screen(textureId, width, height);
}
JNIEXPORT void JNICALL Java_jp_oot_screenrecorder_ScreenRecordNative_releaseGLContext(
JNIEnv * jEnv, jclass jClass) {
printLog(DEBUG, "release GL context");
CustomFrameBuffer::getInstance().release();
CustomFrameTexture::getInstance().release();
}
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jp_oot_screenrecorder_ScreenRecordNative */
#include <Log.h>
#include <CustomFrameBuffer.h>
#include <CustomFrameTexture.h>
#ifndef _Included_jp_oot_screenrecorder_ScreenRecordNative
#define _Included_jp_oot_screenrecorder_ScreenRecordNative
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: jp_oot_screenrecorder_ScreenRecordNative
* Method: initGLContext
* Signature: (II)V
*/
JNIEXPORT void JNICALL Java_jp_oot_screenrecorder_ScreenRecordNative_initGLContext
(JNIEnv *, jclass, jint, jint);
/*
* Class: jp_oot_screenrecorder_ScreenRecordNative
* Method: bindFrameBuffer
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_jp_oot_screenrecorder_ScreenRecordNative_bindFrameBuffer
(JNIEnv *, jclass);
/*
* Class: jp_oot_screenrecorder_ScreenRecordNative
* Method: unbindFrameBuffer
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_jp_oot_screenrecorder_ScreenRecordNative_unbindFrameBuffer
(JNIEnv *, jclass);
/*
* Class: jp_oot_screenrecorder_ScreenRecordNative
* Method: draw2Screen
* Signature: (II)V
*/
JNIEXPORT void JNICALL Java_jp_oot_screenrecorder_ScreenRecordNative_draw2Screen
(JNIEnv *, jclass, jint, jint);
/*
* Class: jp_oot_screenrecorder_ScreenRecordNative
* Method: releaseGLContext
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_jp_oot_screenrecorder_ScreenRecordNative_releaseGLContext
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
#include <Log.h>
int IS_DEBUG_MODE = TRUE;
void printGLString(const char *name, GLenum s) {
if (IS_DEBUG_MODE) {
const char *v = (const char *) glGetString(s);
LOGI("GL %s = %s\n", name, v);
}
}
void printLog(LOG_TYPE type,const char *name, ...){
if(IS_DEBUG_MODE){
va_list params;
char buf[BUFSIZ];
va_start(params, name);
vsprintf(buf, name, params);
if (type == DEBUG)
LOGD("%s", buf);
else if (type == ERROR)
LOGE("%s", buf);
va_end(params);
}
}
void checkGlError(const char* op, ...) {
if (IS_DEBUG_MODE) {
va_list params;
char buf[BUFSIZ];
va_start(params, op);
vsprintf(buf, op, params);
for (GLint error = glGetError(); error; error = glGetError()) {
switch (error) {
case GL_INVALID_ENUM:
LOGE("after %s() glError: GL_INVALID_ENUM \n", buf);
break;
case GL_INVALID_VALUE:
LOGE("after %s() glError: GL_INVALID_VALUE \n", buf);
break;
case GL_INVALID_OPERATION:
LOGE("after %s() glError: GL_INVALID_OPERATION \n", buf);
break;
case GL_INVALID_FRAMEBUFFER_OPERATION:
LOGE("after %s() glError: GL_INVALID_FRAMEBUFFER_OPERATION \n", buf);
break;
case GL_OUT_OF_MEMORY:
LOGE("after %s() glError: GL_OUT_OF_MEMORY \n", buf);
break;
default:
break;
}
}
va_end(params);
}
}
#ifndef LOG_H
#define LOG_H
#include <jni.h>
#include <android/log.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <GLES/glext.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define LOG_TAG "NativeScreenRecord"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#define TRUE 1
#define FALSE 0
enum LOG_TYPE {DEBUG, ERROR} ;
void printGLString(const char *name, GLenum s);
void printLog(LOG_TYPE type,const char *name, ...);
void checkGlError(const char* op, ...);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment