| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "RenderDirectView.h" |
| #include "VideoTex.h" |
| #include "glError.h" |
| #include "shader.h" |
| #include "shader_simpleTex.h" |
| #include "shader_testColors.h" |
| |
| #include <log/log.h> |
| |
| #include <math/mat4.h> |
| |
| |
| RenderDirectView::RenderDirectView(sp<IEvsEnumerator> enumerator, |
| const ConfigManager::CameraInfo& cam) { |
| mEnumerator = enumerator; |
| mCameraInfo = cam; |
| } |
| |
| |
| bool RenderDirectView::activate() { |
| // Ensure GL is ready to go... |
| if (!prepareGL()) { |
| ALOGE("Error initializing GL"); |
| return false; |
| } |
| |
| // Load our shader program if we don't have it already |
| if (!mShaderProgram) { |
| mShaderProgram = buildShaderProgram(vtxShader_simpleTexture, |
| pixShader_simpleTexture, |
| "simpleTexture"); |
| if (!mShaderProgram) { |
| ALOGE("Error buliding shader program"); |
| return false; |
| } |
| } |
| |
| // TODO: Remove this once we're done testing with it |
| if (!mShaderTestColors) { |
| mShaderTestColors = buildShaderProgram(vtxShader_testColors, |
| pixShader_testColors, |
| "testColors"); |
| if (!mShaderTestColors) { |
| ALOGE("Error building shader program"); |
| return false; |
| } |
| } |
| |
| // Construct our video texture |
| mTexture.reset(createVideoTexture(mEnumerator, mCameraInfo.cameraId.c_str(), sDisplay)); |
| if (!mTexture) { |
| ALOGE("Failed to set up video texture for %s (%s)", |
| mCameraInfo.cameraId.c_str(), mCameraInfo.function.c_str()); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| |
| void RenderDirectView::deactivate() { |
| // Release our video texture |
| // We can't hold onto it because some other Render object might need the same camera |
| // TODO: If start/stop costs become a problem, we could share video textures |
| mTexture = nullptr; |
| } |
| |
| |
| bool RenderDirectView::drawFrame(const BufferDesc& tgtBuffer) { |
| // Tell GL to render to the given buffer |
| if (!attachRenderTarget(tgtBuffer)) { |
| ALOGE("Failed to attached render target"); |
| return false; |
| } |
| |
| // Set the viewport |
| glViewport(0, 0, tgtBuffer.width, tgtBuffer.height); |
| |
| #if 0 // We don't actually need the clear if we're going to cover the whole screen anyway |
| // Clear the color buffer |
| glClearColor(0.8f, 0.1f, 0.2f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| #endif |
| |
| // Select our screen space simple texture shader |
| glUseProgram(mShaderProgram); |
| |
| // Set up the model to clip space transform (identity matrix if we're modeling in screen space) |
| GLint loc = glGetUniformLocation(mShaderProgram, "cameraMat"); |
| if (loc < 0) { |
| ALOGE("Couldn't set shader parameter 'cameraMat'"); |
| return false; |
| } else { |
| const android::mat4 identityMatrix; |
| glUniformMatrix4fv(loc, 1, false, &identityMatrix[0][0]); |
| } |
| |
| |
| // Bind the texture and assign it to the shader's sampler |
| mTexture->refresh(); |
| glActiveTexture(GL_TEXTURE0); |
| glBindTexture(GL_TEXTURE_2D, mTexture->glId()); |
| |
| |
| #if 0 |
| static TexWrapper* sTestTexture = createTextureFromPng("/system/etc/automotive/evs/CarFromTop.png"); |
| if (sTestTexture) { |
| static int tickTock = 0; |
| tickTock =~tickTock; |
| if (tickTock) { |
| printf("tick..."); |
| glBindTexture(GL_TEXTURE_2D, sTestTexture->glId()); |
| } else { |
| printf("tock\n"); |
| } |
| } |
| #endif |
| |
| GLint sampler = glGetUniformLocation(mShaderProgram, "tex"); |
| if (sampler < 0) { |
| ALOGE("Couldn't set shader parameter 'tex'"); |
| return false; |
| } else { |
| // Tell the sampler we looked up from the shader to use texture slot 0 as its source |
| glUniform1i(sampler, 0); |
| } |
| |
| // We want our image to show up opaque regardless of alpha values |
| glDisable(GL_BLEND); |
| |
| |
| // Draw a rectangle on the screen |
| // TODO: We pulled in from the edges for now for diagnostic purposes... |
| #if 1 |
| GLfloat vertsCarPos[] = { -1.0, 1.0, 0.0f, // left top in window space |
| 1.0, 1.0, 0.0f, // right top |
| -1.0, -1.0, 0.0f, // left bottom |
| 1.0, -1.0, 0.0f // right bottom |
| }; |
| #else |
| GLfloat vertsCarPos[] = { -0.8, 0.8, 0.0f, // left top in window space |
| 0.8, 0.8, 0.0f, // right top |
| -0.8, -0.8, 0.0f, // left bottom |
| 0.8, -0.8, 0.0f // right bottom |
| }; |
| #endif |
| // TODO: We're flipping horizontally here, but should do it only for specified cameras! |
| GLfloat vertsCarTex[] = { 1.0f, 1.0f, // left top |
| 0.0f, 1.0f, // right top |
| 1.0f, 0.0f, // left bottom |
| 0.0f, 0.0f // right bottom |
| }; |
| glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertsCarPos); |
| glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, vertsCarTex); |
| glEnableVertexAttribArray(0); |
| glEnableVertexAttribArray(1); |
| |
| glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| |
| glDisableVertexAttribArray(0); |
| glDisableVertexAttribArray(1); |
| |
| |
| // Wait for the rendering to finish |
| glFinish(); |
| |
| return true; |
| } |