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); |
+} |