⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 opengl.h

📁 linux下实现视频播放的播放器
💻 H
字号:
/* *  Copyright (C) 2005-2008  gulikoza * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *//* $Id$ */#ifndef OPENGL_H#define OPENGL_H#if (C_OPENGL)#define MODULE "OpenGL"#include "SDL_opengl.h"static const char *FShader =    "uniform sampler2DRect ytex;\n"    "uniform sampler2DRect utex, vtex;\n"    "void main(void) {\n"    "  float nx, ny, r, g, b, y, u, v;\n"    "  vec4 txl, ux, vx;"    "  nx = gl_TexCoord[0].x;\n"    "  ny = gl_TexCoord[0].y;\n"    "  y = texture2DRect(ytex, vec2(nx, ny)).r;\n"    "  u = texture2DRect(utex, vec2(nx/2.0, ny/2.0)).r;\n"    "  v = texture2DRect(vtex, vec2(nx/2.0, ny/2.0)).r;\n"    "  y = 1.1643 * (y - 0.0625);\n"    "  u = u - 0.5;\n"    "  v = v - 0.5;\n"    "  r = y + 1.5958 * v;\n"    "  g = y - 0.39173 * u - 0.81290 * v;\n"    "  b = y + 2.017 * u;\n"    "  gl_FragColor = vec4(r, g, b, 1.0);\n"    "}\n";class OpenGL : public Output {private:    GLuint texobj[3];    unsigned char *texdata;    unsigned short texwidth, texheight;    GLhandleARB fs, p;    GLuint displaylist, PBObuffer;    SDL_Rect display;    PFNGLACTIVETEXTUREARBPROC pglActiveTextureARB;    PFNGLBINDBUFFERARBPROC pglBindBufferARB;    PFNGLMAPBUFFERARBPROC pglMapBufferARB;    PFNGLUNMAPBUFFERARBPROC pglUnmapBufferARB;    void PrintShaderLog(GLhandleARB obj) {	char * log;	int l = 0, w = 0;	PFNGLGETOBJECTPARAMETERIVARBPROC pglGetObjectParameterivARB;	PFNGLGETINFOLOGARBPROC pglGetInfoLogARB;	pglGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)SDL_GL_GetProcAddress("glGetObjectParameterivARB");	pglGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)SDL_GL_GetProcAddress("glGetInfoLogARB");	pglGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &l);	if(l > 0) {	    log = (char *)malloc(sizeof(char)*l);	    pglGetInfoLogARB(obj, l, &w, log);	    ERROR_MSG("%s", ((*log)==' ') ? log+1 : log);	    free(log);	}    }protected:public:    OpenGL():texdata(NULL),fs(0),p(0),displaylist(0),PBObuffer(0),    pglActiveTextureARB(NULL),pglBindBufferARB(NULL),pglMapBufferARB(NULL),pglUnmapBufferARB(NULL) {	texobj[0] = texobj[1] = texobj[2] = 0;	ERROR_MSG("Created " MODULE " object");    }    ~OpenGL() { Free();	ERROR_MSG("Destroyed " MODULE " object"); }    int Create(int w, int h, Uint32 f, SDL_Surface * s) {	GLint res;	// Function pointers	PFNGLUNIFORM1IARBPROC pglUniform1iARB = NULL;	PFNGLGETUNIFORMLOCATIONARBPROC pglGetUniformLocationARB = NULL;	PFNGLCREATESHADEROBJECTARBPROC pglCreateShaderObjectARB = NULL;	PFNGLCREATEPROGRAMOBJECTARBPROC pglCreateProgramObjectARB = NULL;	PFNGLSHADERSOURCEARBPROC pglShaderSourceARB = NULL;	PFNGLCOMPILESHADERARBPROC pglCompileShaderARB = NULL;	PFNGLATTACHOBJECTARBPROC pglAttachObjectARB = NULL;	PFNGLLINKPROGRAMARBPROC	pglLinkProgramARB = NULL;	PFNGLUSEPROGRAMOBJECTARBPROC pglUseProgramObjectARB = NULL;	PFNGLGETOBJECTPARAMETERIVARBPROC pglGetObjectParameterivARB = NULL;	PFNGLGENBUFFERSARBPROC pglGenBuffersARB = NULL;	PFNGLBUFFERDATAARBPROC pglBufferDataARB = NULL;	if((s == NULL) || (s->flags&SDL_OPENGL != SDL_OPENGL)) {	    ERROR_MSG("Could not get OpenGL surface!");	    return -1;	}#if (SDL_IS_PATCHED)	// If SDL is not patched, then OpenGL will fail to initialize	SDL_GL_MakeCurrent(0);#endif	// Need multitexturing and ARB_fragment_shader support	const char *c = (const char*)glGetString(GL_EXTENSIONS);	if(c && (strstr(c, "ARB_fragment_shader")) && (strstr(c, "ARB_multitexture"))) {	    pglActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)SDL_GL_GetProcAddress("glActiveTextureARB");	    pglUniform1iARB = (PFNGLUNIFORM1IARBPROC)SDL_GL_GetProcAddress("glUniform1iARB");	    pglGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)SDL_GL_GetProcAddress("glGetUniformLocationARB");	    pglShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)SDL_GL_GetProcAddress("glShaderSourceARB");	    pglCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)SDL_GL_GetProcAddress("glCompileShaderARB");	    pglCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)SDL_GL_GetProcAddress("glCreateShaderObjectARB");	    pglCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)SDL_GL_GetProcAddress("glCreateProgramObjectARB");	    pglAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)SDL_GL_GetProcAddress("glAttachObjectARB");	    pglLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)SDL_GL_GetProcAddress("glLinkProgramARB");	    pglUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)SDL_GL_GetProcAddress("glUseProgramObjectARB");	    pglGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)SDL_GL_GetProcAddress("glGetObjectParameterivARB");	    if(strstr(c, "ARB_pixel_buffer_object")) {		pglGenBuffersARB = (PFNGLGENBUFFERSARBPROC)SDL_GL_GetProcAddress("glGenBuffersARB");		pglBindBufferARB = (PFNGLBINDBUFFERARBPROC)SDL_GL_GetProcAddress("glBindBufferARB");		pglBufferDataARB = (PFNGLBUFFERDATAARBPROC)SDL_GL_GetProcAddress("glBufferDataARB");		pglMapBufferARB = (PFNGLMAPBUFFERARBPROC)SDL_GL_GetProcAddress("glMapBufferARB");		pglUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)SDL_GL_GetProcAddress("glUnmapBufferARB");	    }	}	if(!pglActiveTextureARB || !pglUniform1iARB || !pglGetUniformLocationARB || !pglShaderSourceARB ||	    !pglCompileShaderARB || !pglCreateShaderObjectARB || !pglCreateProgramObjectARB || !pglAttachObjectARB ||	    !pglLinkProgramARB || !pglUseProgramObjectARB || !pglGetObjectParameterivARB) {	    ERROR_MSG("Required OpenGL functions not supported!");	    return -1;	}	h = h>>half;	width = w; height = h;	format = f; surface = s;	texwidth = ALIGN(w, 64);	texheight = ALIGN(h, 64);	if(pglGenBuffersARB && pglBindBufferARB && pglBufferDataARB &&	   pglMapBufferARB && pglUnmapBufferARB) {	    pglGenBuffersARB(1, &PBObuffer);	    pglBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, PBObuffer);	    pglBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, texwidth * texheight + ((texwidth * texheight)>>1), NULL, GL_STREAM_DRAW_ARB);	    pglBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);	    LOG_MSG("Created %dx%d PBO buffer", texwidth, texheight);	} else {	    texdata = (unsigned char *)_aligned_malloc(texwidth * texheight + ((texwidth * texheight)>>1), 64);	    if(texdata == NULL) {		ERROR_MSG("Out of memory!");		return -1;	    }	    LOG_MSG("Created %dx%d textures", texwidth, texheight);	}	glClearColor(0, 0, 0, 0);	glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);	glShadeModel(GL_FLAT);	glDisable(GL_DEPTH_TEST);	glDisable(GL_LIGHTING);	glDisable(GL_CULL_FACE);	glClear(GL_COLOR_BUFFER_BIT);	glGenTextures(3, texobj);	p = pglCreateProgramObjectARB();	fs = pglCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);	/* Compile the shader */	pglShaderSourceARB(fs, 1, &FShader, NULL);	pglCompileShaderARB(fs);	pglGetObjectParameterivARB(fs, GL_OBJECT_COMPILE_STATUS_ARB, &res);	if(res == 0) {	    ERROR_MSG("Error compiling fragment shader");	    PrintShaderLog(fs);	    return -1;	}	pglAttachObjectARB(p, fs);	pglLinkProgramARB(p);	pglGetObjectParameterivARB(p, GL_OBJECT_LINK_STATUS_ARB, &res);	if(res == 0) {	    ERROR_MSG("Error linking program");	    PrintShaderLog(p);	    return -1;	}#ifndef RELEASE	LOG_MSG("Shader status: ");	PrintShaderLog(p);#endif	pglUseProgramObjectARB(p);	pglActiveTextureARB(GL_TEXTURE1);	glEnable(GL_TEXTURE_RECTANGLE_ARB);	pglUniform1iARB(pglGetUniformLocationARB(p, "utex"), 1);	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);	pglActiveTextureARB(GL_TEXTURE2);	glEnable(GL_TEXTURE_RECTANGLE_ARB);	pglUniform1iARB(pglGetUniformLocationARB(p, "vtex"), 2);	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);	pglActiveTextureARB(GL_TEXTURE0);	glEnable(GL_TEXTURE_RECTANGLE_ARB);	pglUniform1iARB(pglGetUniformLocationARB(p, "ytex"), 0);	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);	// Create display list	displaylist = glGenLists(1);	glNewList(displaylist, GL_COMPILE);	  glBegin(GL_QUADS);	    // lower left	    glTexCoord2f(0, height); glVertex2f(0.0f, 0.0f);	    // lower right	    glTexCoord2f(width, height); glVertex2f(1.0f, 0.0f);	    // upper right	    glTexCoord2f(width, 0); glVertex2f(1.0f, 1.0f);	    // upper left	    glTexCoord2f(0, 0);	glVertex2f(0.0f, 1.0f);	  glEnd();	glEndList();	return 0;    }    void Free(void) {	LOG_MSG("Freeing video surface");	display.w = display.h = 0;	if(displaylist) glDeleteLists(1, displaylist); displaylist = 0;	if(texobj[0]) glDeleteTextures(3, texobj); texobj[0] = texobj[1] = texobj[2] = 0;	if((!PBObuffer) && texdata) _aligned_free(texdata); texdata = NULL;	// Delete PBO buffer	PFNGLDELETEBUFFERSARBPROC pglDeleteBuffersARB;	pglDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)SDL_GL_GetProcAddress("glDeleteBuffersARB");	if(pglDeleteBuffersARB && PBObuffer) pglDeleteBuffersARB(1, &PBObuffer); PBObuffer = 0;	// Delete shaders	PFNGLDETACHOBJECTARBPROC pglDetachObjectARB;	PFNGLDELETEOBJECTARBPROC pglDeleteObjectARB;	pglDetachObjectARB = (PFNGLDETACHOBJECTARBPROC)SDL_GL_GetProcAddress("glDetachObjectARB");	pglDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)SDL_GL_GetProcAddress("glDeleteObjectARB");	if(pglDetachObjectARB && pglDeleteObjectARB && p && fs) {	    pglDetachObjectARB(p, fs);	    pglDeleteObjectARB(fs);	    pglDeleteObjectARB(p);	}#if (SDL_IS_PATCHED)	// Release context if it's current	if(glGetString(GL_EXTENSIONS)) {	    LOG_MSG("Releasing context");	    SDL_GL_MakeCurrent(1);	}#endif	fs = p = 0;    }    int CopyData(struct Buffer *buffer) {	if(deinterlacer->IsHalf() != half) {	    height <<= half;            half = !half;            if(surface) {                Free();                Create(width, height, format, surface);            }        }	if(PBObuffer) {	    pglBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, PBObuffer);	    texdata = (unsigned char*)pglMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY);	}	if(texdata == NULL)	    return -1;	unsigned char * ptr[3];	ptr[2] = texdata;	ptr[0] = texdata + (texwidth * texheight);	ptr[1] = ptr[0] + ((texwidth * texheight)>>2);	if(buffer == NULL) {	    for(int i = height>>1; i; i--) {		SDL_memset(ptr[2], 0, width); ptr[2] += texwidth;		SDL_memset(ptr[2], 0, width); ptr[2] += texwidth;		SDL_memset(ptr[1], 0x80, width>>1); ptr[1] += texwidth>>1;		SDL_memset(ptr[0], 0x80, width>>1); ptr[0] += texwidth>>1;	    }	} else {	    unsigned char *src[3];	    src[2] = buffer->data[0];	    src[0] = buffer->data[1];	    src[1] = buffer->data[2];	    deint d;	    d.src_pitch[2] = buffer->src_width;	    d.src_pitch[0] = d.src_pitch[1] = buffer->src_width>>1;	    d.dst_pitch[2] = texwidth;	    d.dst_pitch[0] = texwidth>>1;	    d.dst_pitch[1] = texwidth>>1;	    d.width = buffer->dst_width;	    d.height = buffer->height;	    Render(ptr, src, &d);	}	if(PBObuffer) {	    pglUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);	    pglBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);	}	return 0;    }    int SwapBuffers(SDL_Rect * clip) {	if(SDL_memcmp(&display, clip, sizeof(SDL_Rect))) {	    SDL_memcpy(&display, clip, sizeof(SDL_Rect));	    glViewport(display.x, display.y, display.w, display.h);	    LOG_MSG("Viewport set to %dx%d", display.w, display.h);	    glMatrixMode(GL_PROJECTION);	    glLoadIdentity();	    glOrtho(0.0f, display.w, 0.0f, display.h, -1.0f, 1.0f);	    glMatrixMode(GL_MODELVIEW);	    glLoadIdentity();	    glScalef(display.w, display.h, 1.0f);	}	glClear(GL_COLOR_BUFFER_BIT);	if((PBObuffer == 0) && (texdata == NULL)) {	    SDL_GL_SwapBuffers();	    return -1;	} else if(PBObuffer) {	    texdata = 0;	    pglBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, PBObuffer);	}	pglActiveTextureARB(GL_TEXTURE0);	glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texobj[0]);	glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, texwidth, texheight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, texdata);	pglActiveTextureARB(GL_TEXTURE1);	glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texobj[1]);	glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, texwidth>>1, texheight>>1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,			texdata + (texwidth * texheight));	pglActiveTextureARB(GL_TEXTURE2);	glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texobj[2]);	glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, texwidth>>1, texheight>>1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,			texdata + (texwidth * texheight) + ((texwidth * texheight)>>2));	if(PBObuffer) {	    pglBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);	}	glCallList(displaylist);	SDL_GL_SwapBuffers();	return 0;    }};#undef MODULE#endif // C_OPENGL#endif // OPENGL_H

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -