2 Copyright 2012 Marten Richter
\r
4 This file is part of VOMP.
\r
6 VOMP is free software; you can redistribute it and/or modify
\r
7 it under the terms of the GNU General Public License as published by
\r
8 the Free Software Foundation; either version 2 of the License, or
\r
9 (at your option) any later version.
\r
11 VOMP is distributed in the hope that it will be useful,
\r
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 GNU General Public License for more details.
\r
16 You should have received a copy of the GNU General Public License
\r
17 along with VOMP; if not, write to the Free Software
\r
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
\r
20 #include "glmocoshader.h"
\r
21 #include "videovpeogl.h"
\r
23 const GLchar moco_vertex_shader[] =
\r
24 "attribute vec4 vec_pos;\n"
\r
25 "attribute vec2 tex_coord;\n"
\r
26 "varying vec2 out_texCoord;\n"
\r
29 " gl_Position=vec_pos;\n"
\r
30 " out_texCoord=tex_coord;\n"
\r
33 const GLchar moco_frag_shader[] =
\r
34 "precision mediump float;\n"
\r
35 "uniform sampler2D textureU;\n"
\r
36 "uniform sampler2D textureV;\n"
\r
37 "uniform sampler2D textureY;\n"
\r
38 "const float uv_corr=0.5;\n"
\r
39 "const float y_corr=0.0625;\n"
\r
40 "const mat3 yuvtransform= mat3( 1.164 ,0.0 ,1.596 ,\n"
\r
41 " 1.164 ,-0.391,-0.813 ,\n"
\r
42 " 1.164,2.018 , 0.0 );\n"
\r
43 // "const mat3 yuvtransform= mat3( 1. ,1. ,1. ,\n"
\r
44 // " 0.0 ,-0.3960,2.029 ,\n"
\r
45 // " 1.140,-0.581 , 0.0 );\n"
\r
46 // "const mat3 yuvtransform= mat3( 1. ,0 ,0. ,\n"
\r
47 // " 0.0 ,1.,0. ,\n"
\r
48 // " 0.,0. , 1.0 );\n"
\r
49 // "const mat3 yuvtransform= mat3( 1. ,1. ,1. ,\n"
\r
50 // " 0.0 ,-0.03960,0.2029 ,\n"
\r
51 // " 0.1140,-0.0581 , 0.0 );\n"
\r
52 "varying vec2 out_texCoord;\n"
\r
56 "help.x=texture2D(textureY,out_texCoord).r-y_corr;\n"
\r
57 "help.y=texture2D(textureU,out_texCoord).r-uv_corr;\n"
\r
58 "help.z=texture2D(textureV,out_texCoord).r-uv_corr;\n" //-uv_corr;\n"
\r
59 " gl_FragColor.rgb=help*yuvtransform;\n"
\r
60 " gl_FragColor.a=1.;\n"
\r
63 GLMocoShader::GLMocoShader(): GLShader("GLYuv400Shader")
\r
69 GLMocoShader::~GLMocoShader()
\r
71 //parent does everything
\r
74 int GLMocoShader::init() {
\r
75 if (!initShaders(moco_vertex_shader, moco_frag_shader)) {
\r
78 // frame_sampler_locY = glGetUniformLocation(shad_program, "textureY");
\r
79 // Log::getInstance()->log("OSD", Log::WARN, "uniform location %x %x",frame_sampler_locY,glGetError());
\r
80 // frame_sampler_locU = glGetUniformLocation(shad_program, "textureU");
\r
81 //Log::getInstance()->log("OSD", Log::WARN, "uniform location %x %x",frame_sampler_locU,glGetError());
\r
82 // frame_sampler_locV = glGetUniformLocation(shad_program, "textureV");
\r
83 glGenFramebuffers(1, &frame_buf);
\r
84 glGenTextures(1, &data_blocks);
\r
85 glBindTexture(GL_TEXTURE_2D, data_blocks);
\r
86 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1024, 1024, 0, GL_LUMINANCE_ALPHA,
\r
87 GL_UNSIGNED_BYTE, NULL);
\r
89 glGenBuffers(1,¯o_block);
\r
90 glBindBuffer(GL_ARRAY_BUFFER,macro_block);
\r
91 glBufferData(GL_ARRAY_BUFFER,4096*4*sizeof(XvMCMacroBlock),NULL,GL_DYNAMIC_DRAW);
\r
92 valid_macro_blocks=0;
\r
95 glGenBuffers(1,&triangles);
\r
96 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,triangles);
\r
97 GLushort *tri_indices=(GLushort *)malloc(sizeof(GLushort)*4096*6);
\r
99 Log::getInstance()->log("GLMocoShader", Log::WARN, "allocating triindices failed");
\r
102 GLushort *tri_indices_run=tri_indices;
\r
103 for (int i=0;i<4096;i++) {
\r
104 *tri_indices_run=i+2*4096; //strip
\r
106 *tri_indices_run=i+0*4096; //strip
\r
108 *tri_indices_run=i+3*4096; //strip
\r
110 *tri_indices_run=i+1*4096; //strip
\r
112 *tri_indices_run=i+1*4096; //strip
\r
114 *tri_indices_run=i+1+2*4096; //strip
\r
117 glBufferData(GL_ELEMENT_ARRAY_BUFFER,4096*6*sizeof(GLushort),tri_indices,GL_STREAM_DRAW);
\r
120 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
\r
121 glBindBuffer(GL_ARRAY_BUFFER,0);
\r
129 int GLMocoShader::deinit()
\r
131 glDeleteFramebuffers(1, &frame_buf);
\r
132 glDeleteTextures(1, &frame_buf);
\r
133 return deinitShaders();
\r
136 int GLMocoShader::uploadDataBlocks(short* blocks,unsigned int num_blocks, XvMCMacroBlock *m_blocks,unsigned int num_m_blocks)
\r
138 unsigned int height=(num_blocks+127)/128;
\r
140 glBindTexture(GL_TEXTURE_2D, data_blocks);
\r
141 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
\r
143 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
\r
145 GL_LUMINANCE,GL_UNSIGNED_BYTE,
\r
147 //Log::getInstance()->log("GLMocoShader", Log::WARN, "uploadDataBlocks mark2 glerror %x",glGetError());
\r
149 valid_macro_blocks=num_m_blocks;
\r
150 glBindBuffer(GL_ARRAY_BUFFER,macro_block);
\r
151 XvMCMacroBlock *m_blocks_run=m_blocks;
\r
152 XvMCMacroBlock *m_blocks_end=m_blocks+num_m_blocks;
\r
153 while (m_blocks_run!=m_blocks_end) {
\r
154 m_blocks_run->pad0=0x0000;
\r
157 glBufferSubData(GL_ARRAY_BUFFER, 0, num_m_blocks * sizeof(XvMCMacroBlock),
\r
160 m_blocks_run = m_blocks;
\r
161 m_blocks_end = m_blocks + num_m_blocks;
\r
162 while (m_blocks_run != m_blocks_end) {
\r
163 m_blocks_run->pad0 = 0x00FF;
\r
166 glBufferSubData(GL_ARRAY_BUFFER, 4096, num_m_blocks * sizeof(XvMCMacroBlock),
\r
169 m_blocks_run = m_blocks;
\r
170 m_blocks_end = m_blocks + num_m_blocks;
\r
171 while (m_blocks_run != m_blocks_end) {
\r
172 m_blocks_run->pad0 = 0xFF00;
\r
175 glBufferSubData(GL_ARRAY_BUFFER, 2 * 4096,
\r
176 num_m_blocks * sizeof(XvMCMacroBlock), m_blocks);
\r
178 m_blocks_run = m_blocks;
\r
179 m_blocks_end = m_blocks + num_m_blocks;
\r
180 while (m_blocks_run != m_blocks_end) {
\r
181 m_blocks_run->pad0 = 0xFFFF;
\r
184 glBufferSubData(GL_ARRAY_BUFFER, 3 * 4096,
\r
185 num_m_blocks * sizeof(XvMCMacroBlock), m_blocks);
\r
188 glBindBuffer(GL_ARRAY_BUFFER,0);
\r
196 int GLMocoShader::doMoCo(VPEOGLFrame *target, VPE_FrameBuf* source)
\r
199 glBindFramebuffer(GL_FRAMEBUFFER, frame_buf);
\r
200 Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark1 glerror %x",glGetError());
\r
201 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
\r
202 GL_TEXTURE_2D, target->textures[0], 0);
\r
203 Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark2 glerror %x",glGetError());
\r
205 int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
\r
206 if (status == GL_FRAMEBUFFER_COMPLETE) {
\r
207 glUseProgram(shad_program);
\r
208 Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark3 glerror %x",glGetError());
\r
211 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
\r
212 glBindBuffer(GL_ARRAY_BUFFER,0);
\r
213 glBindFramebuffer(GL_FRAMEBUFFER, 0);
\r
215 glBindFramebuffer(GL_FRAMEBUFFER, 0);
\r
216 Log::getInstance()->log("GLMocoShader", Log::WARN, "framebuffer not complete");
\r
227 int GLMocoShader::PrepareRendering(GLuint y_tex, GLuint u_tex, GLuint v_tex) { // This Function setups the rendering pipeline according to the shaders standards
\r
229 //Log::getInstance()->log("OSD", Log::WARN, "mark1 glerror %x",glGetError());
\r
232 //Log::getInstance()->log("OSD", Log::WARN, "mark2 glerror %x",glGetError());
\r
235 glActiveTexture( GL_TEXTURE2);
\r
236 glBindTexture(GL_TEXTURE_2D, v_tex);
\r
237 glUniform1i(frame_sampler_locV, 2);
\r
238 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
239 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
241 glActiveTexture( GL_TEXTURE1);
\r
242 glBindTexture(GL_TEXTURE_2D, u_tex);
\r
243 glUniform1i(frame_sampler_locU, 1);
\r
244 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
245 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
247 glActiveTexture( GL_TEXTURE0);
\r
248 glBindTexture(GL_TEXTURE_2D, y_tex);
\r
249 glUniform1i(frame_sampler_locY, 0);
\r
250 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
251 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
256 int GLMocoShader::BindAttributes()
\r
258 glBindAttribLocation(shad_program,0,"vec_pos");
\r
259 glBindAttribLocation(shad_program,1,"tex_coord");
\r