- 论坛徽章:
- 11
|
本帖最后由 zylthinking 于 2012-09-28 15:32 编辑
- #ifndef stage_h
- #define stage_h
- #include <OpenGLES/ES1/gl.h>
- #include <OpenGLES/ES1/glext.h>
- #include "../../inc/mixer.h"
- struct stage_struct {
- int ref;
- struct window* layer;
- GLuint rendbuf;
- GLuint texture_obj;
- GLuint vao_id, vertex_fbo, texture_fbo;
- int z, w, h;
- };
- struct stage_struct* find_stage(struct window* layer);
- void release_stage(struct stage_struct* stage);
- void rend_to_stage(struct stage_struct* stage, int x0, int y0, int x1, int y1, int z, struct audio_buffer* stream);
- #endif
- static int llk = 0;
- static GLuint framebuffer = 0;
- static EAGLContext* context = NULL;
- struct stage_struct stages[max_audio_stream] = {0};
- static void* video_init()
- {
- if (context != NULL) {
- return context;
- }
- lock(&llk);
- if (context != NULL) {
- unlock(&llk);
- return context;
- }
- if (framebuffer == 0) {
- glShadeModel(GL_FLAT);
- glEnable(GL_DEPTH_TEST);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glEnable(GL_TEXTURE_2D);
- glGenFramebuffersOES(1, &framebuffer);
- glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
- }
- context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES1];
- if (context != NULL) {
- [EAGLContext setCurrentContext:context];
- }
- unlock(&llk);
- return context;
- }
- #define check_init(err) do { \
- if (NULL == video_init()) { \
- return err; \
- } \
- } while (0)
- static void create_vertex_objects(struct stage_struct* stage)
- {
- struct window* layer = stage->layer;
- glGenVertexArraysOES(1, &stage->vao_id);
- glBindVertexArrayOES(stage->vao_id);
- GLfloat vertexes[] = {
- layer->x, layer->y, 0.0,
- layer->x + layer->w, layer->y, 0.0,
- layer->x, layer->y + layer->h, 0.0,
- layer->x + layer->w, layer->y + layer->h, 0.0,
- layer->x, layer->y, 1.0,
- layer->x + layer->w, layer->y, 1.0,
- layer->x, layer->y + layer->h, 1.0,
- layer->x + layer->w, layer->y + layer->h, 1.0,
- };
- glOrthof(layer->x, layer->x + layer->w,
- layer->y, layer->y + layer->h, 1.0, -1.0);
- glGenBuffers(1, &stage->vertex_fbo);
- glBindBuffer(GL_ARRAY_BUFFER, stage->vertex_fbo);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vertexes), vertexes, GL_STATIC_DRAW);
- glVertexPointer(3, GL_FLOAT, 0, (GLvoid *) NULL);
- glEnableClientState(GL_VERTEX_ARRAY);
- stage->z = 0;
- GLfloat textures[] = {
- 0.0, 0.0,
- 1.0, 0.0,
- 0.0, 1.0,
- 1.0, 1.0
- };
- glGenBuffers(1, &stage->texture_fbo);
- glBindBuffer(GL_ARRAY_BUFFER, stage->texture_fbo);
- glBufferData(GL_ARRAY_BUFFER, sizeof(textures), textures, GL_STATIC_DRAW);
- glTexCoordPointer(2, GL_FLOAT, 0, (GLvoid *) NULL);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glGenTextures(1, &stage->texture_obj);
- glBindTexture(GL_TEXTURE_2D, stage->texture_obj);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- }
- struct stage_struct* find_stage(struct window* layer)
- {
- check_init(NULL);
- int i;
- struct stage_struct* stage = NULL;
- lock(&llk);
- for (i = 0; i < elements(context); ++i) {
- if (stages[i].layer == NULL) {
- if (stage == NULL) {
- stage = &stages[i];
- }
- continue;
- }
- if (stages[i].layer == layer) {
- stage = &stages[i];
- break;
- }
- }
- if (stage != NULL) {
- if (i == elements(context)) {
- glGenRenderbuffersOES(1, &stage->rendbuf);
- stage->layer = layer;
- stage->w = stage->h = 0;
- create_vertex_objects(stage);
- CAEAGLLayer* ptr = (CAEAGLLayer *) layer->surface;
- ptr.opaque = TRUE;
- [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:ptr];
- glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, stage->rendbuf);
- }
- stage->ref += 1;
- }
- unlock(&llk);
- return stage;
- }
- void release_stage(struct stage_struct* stage)
- {
- assert(stage && stage->layer != NULL);
- lock(&llk);
- if (0 == (--stage->ref)) {
- stage->layer = NULL;
- glDeleteRenderbuffersOES(1, &stage->rendbuf);
- glDeleteVertexArraysOES(1, &stage->vao_id);
- glDeleteTextures(1, &stage->texture_obj);
- glDeleteBuffers(1, &stage->vertex_fbo);
- glDeleteBuffers(1, &stage->texture_fbo);
- }
- unlock(&llk);
- }
- void rend_to_stage(struct stage_struct* stage,
- int x0, int y0, int x1, int y1, int z, struct audio_buffer* stream)
- {
- assert(z == 0 || z == 1);
- assert(stage->layer != NULL);
- EAGLContext *current = [EAGLContext currentContext];
- assert(current == context);
- VideoHeader* video_header = (VideoHeader *) &stream->buffer[stream->length];
- glBindTexture(GL_TEXTURE_2D, stage->texture_obj);
- int same = (stage->w == video_header->nWidth && stage->h == video_header->nHeight);
- if (__buildin_expect(!same, 0)) {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, video_header->nWidth,
- video_header->nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, stream->buffer);
- stage->w = video_header->nWidth;
- stage->h = video_header->nHeight;
- } else {
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, video_header->nWidth,
- video_header->nHeight, GL_RGBA, GL_UNSIGNED_BYTE, stream->buffer);
- }
- glViewport(x0, y0, (x1 - x0), (y1 - y0));
- glBindVertexArrayOES(stage->vao_id);
- if (z != stage->z) {
- glVertexPointer(3, GL_FLOAT, 0, (GLvoid *) (sizeof(GLfloat) * z * 12));
- stage->z = z;
- }
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- [context presentRenderbuffer:GL_RENDERBUFFER_OES];
- }
复制代码 |
|