-
Notifications
You must be signed in to change notification settings - Fork 880
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
35 changed files
with
1,487 additions
and
1,037 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
cmake_minimum_required(VERSION 3.4.1) | ||
set(CMAKE_CXX_STANDARD 14) | ||
|
||
add_library(camerakit-core SHARED | ||
camerakit/CameraSurfaceTexture.cpp | ||
camerakit/CameraSurfaceTexture.hpp | ||
camerakit/CameraSurfaceView.cpp | ||
camerakit/CameraSurfaceView.hpp) | ||
|
||
target_link_libraries(camerakit-core | ||
PUBLIC -llog | ||
PUBLIC -lGLESv2) | ||
|
||
add_library(camerakit SHARED | ||
jni_camera_surface_texture.cpp | ||
jni_camera_surface_view.cpp | ||
main.cpp) | ||
|
||
target_link_libraries(camerakit | ||
PUBLIC camerakit-core) |
214 changes: 214 additions & 0 deletions
214
camerakit/src/main/cpp/camerakit/CameraSurfaceTexture.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,214 @@ | ||
#include "CameraSurfaceTexture.hpp" | ||
|
||
namespace camerakit { | ||
|
||
CameraSurfaceTexture::CameraSurfaceTexture(GLuint inputTexture, GLuint outputTexture) | ||
: width(0), | ||
height(0) { | ||
|
||
this->inputTexture = inputTexture; | ||
this->outputTexture = outputTexture; | ||
|
||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, inputTexture); | ||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
|
||
glGenBuffers(1, &vertexBuffer); | ||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); | ||
glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), VertexData(), GL_STATIC_DRAW); | ||
|
||
GLuint program = CreateProgram(VertexShaderCode(), FragmentShaderCode()); | ||
if (!program) { | ||
// TODO: throw here | ||
return; | ||
} | ||
|
||
glUseProgram(program); | ||
|
||
GLint aPosition = glGetAttribLocation(program, "aPosition"); | ||
GLint aTexCoord = glGetAttribLocation(program, "aTexCoord"); | ||
GLint uTransformMatrix = glGetUniformLocation(program, "uTransformMatrix"); | ||
GLint uRotationMatrix = glGetUniformLocation(program, "uRotationMatrix"); | ||
|
||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | ||
|
||
if (glGetError() != GL_NO_ERROR) { | ||
glDeleteProgram(program); | ||
|
||
// TODO: throw here | ||
return; | ||
} | ||
|
||
this->program = program; | ||
this->aPosition = aPosition; | ||
this->aTexCoord = aTexCoord; | ||
this->uTransformMatrix = uTransformMatrix; | ||
this->uRotationMatrix = uRotationMatrix; | ||
} | ||
|
||
CameraSurfaceTexture::~CameraSurfaceTexture() { | ||
if (vertexBuffer != 0) { | ||
glDeleteBuffers(1, &vertexBuffer); | ||
vertexBuffer = 0; | ||
} | ||
} | ||
|
||
void CameraSurfaceTexture::setSize(int width, int height) { | ||
this->width = width; | ||
this->height = height; | ||
|
||
if (glIsFramebuffer(framebuffer)) { | ||
glDeleteFramebuffers(1, &framebuffer); | ||
} | ||
|
||
glGenFramebuffers(1, &framebuffer); | ||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); | ||
glBindTexture(GL_TEXTURE_2D, outputTexture); | ||
|
||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); | ||
|
||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
glTexParameteri(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); | ||
|
||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, outputTexture, 0); | ||
glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||
} | ||
|
||
void CameraSurfaceTexture::updateTexImage(float* transformMatrix, float* rotationMatrix) { | ||
glViewport(0, 0, width, height); | ||
|
||
glBindTexture(GL_TEXTURE_2D, 0); | ||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); | ||
|
||
glDisable(GL_BLEND); | ||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, inputTexture); | ||
|
||
glUseProgram(program); | ||
glUniformMatrix4fv(uTransformMatrix, 1, GL_FALSE, transformMatrix); | ||
glUniformMatrix4fv(uRotationMatrix, 1, GL_FALSE, rotationMatrix); | ||
glVertexAttribPointer(aPosition, 4, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (const GLvoid*) (0 * sizeof(GLfloat))); | ||
glEnableVertexAttribArray(aPosition); | ||
glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (const GLvoid*) (4 * sizeof(GLfloat))); | ||
glEnableVertexAttribArray(aTexCoord); | ||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); | ||
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, VertexIndices()); | ||
} | ||
|
||
const GLfloat* CameraSurfaceTexture::VertexData() { | ||
static const GLfloat vertexData[] = { | ||
-1.0f, -1.0f, 0.0, 1.0, 0.0f, 0.0f, | ||
+1.0f, -1.0f, 0.0, 1.0, 1.0f, 0.0f, | ||
-1.0f, +1.0f, 0.0, 1.0, 0.0f, 1.0f, | ||
+1.0f, +1.0f, 0.0, 1.0, 1.0f, 1.0f, | ||
}; | ||
|
||
return vertexData; | ||
} | ||
|
||
const GLushort* CameraSurfaceTexture::VertexIndices() { | ||
static const GLushort vertexIndices[] = { | ||
0, 1, 2, 3 | ||
}; | ||
|
||
return vertexIndices; | ||
} | ||
|
||
const char* CameraSurfaceTexture::VertexShaderCode() { | ||
static const char vertexShader[] = | ||
"uniform mat4 uTransformMatrix;\n" | ||
"uniform mat4 uRotationMatrix;\n" | ||
"attribute vec4 aPosition;\n" | ||
"attribute vec4 aTexCoord;\n" | ||
"varying vec2 vTexCoord;\n" | ||
"void main() {\n" | ||
" gl_Position = uRotationMatrix * aPosition;\n" | ||
" vTexCoord = (uTransformMatrix * aTexCoord).xy;\n" | ||
"}\n"; | ||
|
||
return vertexShader; | ||
} | ||
|
||
const char* CameraSurfaceTexture::FragmentShaderCode() { | ||
static const char fragmentShader[] = | ||
"#extension GL_OES_EGL_image_external:require\n" | ||
"precision mediump float;\n" | ||
"uniform samplerExternalOES uTexture;\n" | ||
"varying vec2 vTexCoord;\n" | ||
"void main() {\n" | ||
" gl_FragColor = texture2D(uTexture, vTexCoord);\n" | ||
"}\n"; | ||
|
||
return fragmentShader; | ||
} | ||
|
||
GLuint CameraSurfaceTexture::LoadShader(GLenum shaderType, const char* shaderCode) { | ||
GLuint shader = glCreateShader(shaderType); | ||
if (shader) { | ||
glShaderSource(shader, 1, &shaderCode, NULL); | ||
glCompileShader(shader); | ||
GLint compileStatus = GL_FALSE; | ||
glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus); | ||
if (!compileStatus) { | ||
GLint infoLength = 0; | ||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLength); | ||
if (infoLength) { | ||
char* infoBuffer = (char*) malloc((size_t) infoLength); | ||
if (infoBuffer) { | ||
glGetShaderInfoLog(shader, infoLength, NULL, infoBuffer); | ||
// todo: output log | ||
free(infoBuffer); | ||
} | ||
} | ||
glDeleteShader(shader); | ||
shader = 0; | ||
} | ||
} | ||
return shader; | ||
} | ||
|
||
GLuint CameraSurfaceTexture::CreateProgram(const char* vertexShaderCode, | ||
const char* fragmentShaderCode) { | ||
GLuint vertexShader = LoadShader(GL_VERTEX_SHADER, vertexShaderCode); | ||
if (!vertexShader) { | ||
return 0; | ||
} | ||
|
||
GLuint fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fragmentShaderCode); | ||
if (!fragmentShader) { | ||
return 0; | ||
} | ||
|
||
GLuint program = glCreateProgram(); | ||
if (program) { | ||
glAttachShader(program, vertexShader); | ||
// TODO: check error and throw if needed | ||
|
||
glAttachShader(program, fragmentShader); | ||
// TODO: check error and throw if needed | ||
|
||
glLinkProgram(program); | ||
GLint linkStatus = GL_FALSE; | ||
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); | ||
if (!linkStatus) { | ||
GLint infoLength = 0; | ||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLength); | ||
if (infoLength) { | ||
char* infoBuffer = (char*) malloc((size_t) infoLength); | ||
if (infoBuffer) { | ||
glGetProgramInfoLog(program, infoLength, NULL, infoBuffer); | ||
// todo: output log | ||
free(infoBuffer); | ||
} | ||
} | ||
glDeleteProgram(program); | ||
program = 0; | ||
} | ||
} | ||
return program; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#pragma once | ||
|
||
#include <GLES2/gl2.h> | ||
#include <GLES2/gl2ext.h> | ||
#include <android/log.h> | ||
|
||
#include <stdlib.h> | ||
|
||
#define LOG_TAG "CameraSurfaceTexture" | ||
#define LOG_DEBUG(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) | ||
#define LOG_ERROR(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) | ||
|
||
namespace camerakit { | ||
|
||
class CameraSurfaceTexture { | ||
|
||
public: | ||
CameraSurfaceTexture(GLuint inputTexture, GLuint outputTexture); | ||
virtual ~CameraSurfaceTexture(); | ||
|
||
public: | ||
void setSize(int width, int height); | ||
void updateTexImage(float* transformMatrix, float* rotationMatrix); | ||
|
||
private: | ||
int width; | ||
int height; | ||
|
||
GLuint inputTexture; | ||
GLuint outputTexture; | ||
GLuint framebuffer; | ||
GLuint vertexBuffer; | ||
|
||
GLuint program; | ||
GLint aPosition; | ||
GLint aTexCoord; | ||
GLint uTransformMatrix; | ||
GLint uRotationMatrix; | ||
|
||
private: | ||
static const GLfloat* VertexData(); | ||
static const GLushort* VertexIndices(); | ||
|
||
static const char* VertexShaderCode(); | ||
static const char* FragmentShaderCode(); | ||
|
||
static GLuint LoadShader(GLenum shaderType, const char* shaderCode); | ||
static GLuint CreateProgram(const char* vertexShaderCode, const char* fragmentShaderCode); | ||
|
||
}; | ||
|
||
} |
Oops, something went wrong.