| Index: webrtc/sdk/objc/Framework/Classes/RTCShader.mm
|
| diff --git a/webrtc/sdk/objc/Framework/Classes/RTCShader.mm b/webrtc/sdk/objc/Framework/Classes/RTCShader.mm
|
| index 88082064dfdf3749f4948a7b0be9bda35378572b..26dc64f92bb32d9cd321ff1e336969a62cee9912 100644
|
| --- a/webrtc/sdk/objc/Framework/Classes/RTCShader.mm
|
| +++ b/webrtc/sdk/objc/Framework/Classes/RTCShader.mm
|
| @@ -10,6 +10,8 @@
|
|
|
| #import "RTCShader.h"
|
|
|
| +#include <algorithm>
|
| +#include <array>
|
| #include <memory>
|
|
|
| #import "RTCShader+Private.h"
|
| @@ -28,21 +30,6 @@ const char kRTCVertexShaderSource[] =
|
| " v_texcoord = texcoord;\n"
|
| "}\n";
|
|
|
| -// When modelview and projection matrices are identity (default) the world is
|
| -// contained in the square around origin with unit size 2. Drawing to these
|
| -// coordinates is equivalent to drawing to the entire screen. The texture is
|
| -// stretched over that square using texture coordinates (u, v) that range
|
| -// from (0, 0) to (1, 1) inclusive. Texture coordinates are flipped vertically
|
| -// here because the incoming frame has origin in upper left hand corner but
|
| -// OpenGL expects origin in bottom left corner.
|
| -static const GLfloat gVertices[] = {
|
| - // X, Y, U, V.
|
| - -1, -1, 0, 1, // Bottom left.
|
| - 1, -1, 1, 1, // Bottom right.
|
| - 1, 1, 1, 0, // Top right.
|
| - -1, 1, 0, 0, // Top left.
|
| -};
|
| -
|
| // Compiles a shader of the given |type| with GLSL source |source| and returns
|
| // the shader handle or 0 on error.
|
| GLuint RTCCreateShader(GLenum type, const GLchar *source) {
|
| @@ -111,9 +98,8 @@ GLuint RTCCreateProgramFromFragmentSource(const char fragmentShaderSource[]) {
|
| return program;
|
| }
|
|
|
| -// Set vertex shader variables 'position' and 'texcoord' in |program| to the
|
| -// |gVertices| array above. It will use |vertexBuffer| and |vertexArray| to
|
| -// store the vertex data.
|
| +// Set vertex shader variables 'position' and 'texcoord' in |program| to use
|
| +// |vertexBuffer| and |vertexArray| to store the vertex data.
|
| BOOL RTCSetupVerticesForProgram(GLuint program, GLuint* vertexBuffer, GLuint* vertexArray) {
|
| GLint position = glGetAttribLocation(program, "position");
|
| GLint texcoord = glGetAttribLocation(program, "texcoord");
|
| @@ -132,11 +118,11 @@ BOOL RTCSetupVerticesForProgram(GLuint program, GLuint* vertexBuffer, GLuint* ve
|
| return NO;
|
| }
|
| glBindBuffer(GL_ARRAY_BUFFER, *vertexBuffer);
|
| - glBufferData(GL_ARRAY_BUFFER, sizeof(gVertices), gVertices, GL_DYNAMIC_DRAW);
|
| + glBufferData(GL_ARRAY_BUFFER, 4 * 4 * sizeof(GLfloat), NULL, GL_DYNAMIC_DRAW);
|
|
|
| - // Read position attribute from |gVertices| with size of 2 and stride of 4
|
| - // beginning at the start of the array. The last argument indicates offset
|
| - // of data within |gVertices| as supplied to the vertex buffer.
|
| + // Read position attribute with size of 2 and stride of 4 beginning at the
|
| + // start of the array. The last argument indicates offset of data within the
|
| + // vertex buffer.
|
| glVertexAttribPointer(position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat),
|
| (void *)0);
|
| glEnableVertexAttribArray(position);
|
| @@ -150,3 +136,49 @@ BOOL RTCSetupVerticesForProgram(GLuint program, GLuint* vertexBuffer, GLuint* ve
|
|
|
| return YES;
|
| }
|
| +
|
| +// Set vertex data to the currently bound vertex buffer.
|
| +void RTCSetVertexData(webrtc::VideoRotation rotation) {
|
| + // When modelview and projection matrices are identity (default) the world is
|
| + // contained in the square around origin with unit size 2. Drawing to these
|
| + // coordinates is equivalent to drawing to the entire screen. The texture is
|
| + // stretched over that square using texture coordinates (u, v) that range
|
| + // from (0, 0) to (1, 1) inclusive. Texture coordinates are flipped vertically
|
| + // here because the incoming frame has origin in upper left hand corner but
|
| + // OpenGL expects origin in bottom left corner.
|
| + std::array<std::array<GLfloat, 2>, 4> UVCoords = {{
|
| + {{0, 1}}, // Lower left.
|
| + {{1, 1}}, // Lower right.
|
| + {{1, 0}}, // Upper right.
|
| + {{0, 0}}, // Upper left.
|
| + }};
|
| +
|
| + // Rotate the UV coordinates.
|
| + int rotation_offset;
|
| + switch (rotation) {
|
| + case webrtc::kVideoRotation_0:
|
| + rotation_offset = 0;
|
| + break;
|
| + case webrtc::kVideoRotation_90:
|
| + rotation_offset = 1;
|
| + break;
|
| + case webrtc::kVideoRotation_180:
|
| + rotation_offset = 2;
|
| + break;
|
| + case webrtc::kVideoRotation_270:
|
| + rotation_offset = 3;
|
| + break;
|
| + }
|
| + std::rotate(UVCoords.begin(), UVCoords.begin() + rotation_offset,
|
| + UVCoords.end());
|
| +
|
| + const GLfloat gVertices[] = {
|
| + // X, Y, U, V.
|
| + -1, -1, UVCoords[0][0], UVCoords[0][1],
|
| + 1, -1, UVCoords[1][0], UVCoords[1][1],
|
| + 1, 1, UVCoords[2][0], UVCoords[2][1],
|
| + -1, 1, UVCoords[3][0], UVCoords[3][1],
|
| + };
|
| +
|
| + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(gVertices), gVertices);
|
| +}
|
|
|