4
* ***** BEGIN GPL LICENSE BLOCK *****
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version. The Blender
10
* Foundation also sells licenses for use in proprietary software under
11
* the Blender License. See http://www.blender.org/BL/ for information
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software Foundation,
21
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
* The Original Code is Copyright (C) 2005 Blender Foundation.
24
* All rights reserved.
26
* The Original Code is: all of this file.
28
* Contributor(s): Brecht Van Lommel.
30
* ***** END GPL LICENSE BLOCK *****
35
#include "DNA_listBase.h"
36
#include "DNA_image_types.h"
37
#include "DNA_userdef_types.h"
39
#include "MEM_guardedalloc.h"
41
#include "BKE_image.h"
42
#include "BKE_global.h"
43
#include "BKE_utildefines.h"
45
#include "IMB_imbuf.h"
46
#include "IMB_imbuf_types.h"
48
#include "BLI_blenlib.h"
51
#include "GPU_extensions.h"
57
/* Extensions support */
60
- texture border clamp: 1.3 core
61
- fragement shader: 2.0 core
62
- framebuffer object: ext specification
63
- multitexture 1.3 core
64
- arb non power of two: 2.0 core
65
- pixel buffer objects? 2.1 core
66
- arb draw buffers? 2.0 core
69
static struct GPUGlobal {
76
void GPU_extensions_disable()
81
void GPU_extensions_init()
85
/* glewIsSupported("GL_VERSION_2_0") */
87
if (GLEW_ARB_multitexture)
88
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &GG.maxtextures);
90
GG.minimumsupport = 1;
91
if (!GLEW_ARB_multitexture) GG.minimumsupport = 0;
92
if (!GLEW_ARB_vertex_shader) GG.minimumsupport = 0;
93
if (!GLEW_ARB_fragment_shader) GG.minimumsupport = 0;
96
int GPU_extensions_minimum_support()
98
return !GG.extdisabled && GG.minimumsupport;
101
int GPU_print_error(char *str)
106
if ((errCode = glGetError()) != GL_NO_ERROR) {
107
fprintf(stderr, "%s opengl error: %s\n", str, gluErrorString(errCode));
115
static void GPU_print_framebuffer_error(GLenum status)
117
fprintf(stderr, "GPUFrameBuffer: framebuffer incomplete error %d\n",
121
case GL_FRAMEBUFFER_COMPLETE_EXT:
123
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
124
fprintf(stderr, "Incomplete attachment.\n");
126
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
127
fprintf(stderr, "Unsupported framebuffer format.\n");
129
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
130
fprintf(stderr, "Missing attachment.\n");
132
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
133
fprintf(stderr, "Attached images must have same dimensions.\n");
135
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
136
fprintf(stderr, "Attached images must have same format.\n");
138
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
139
fprintf(stderr, "Missing draw buffer.\n");
141
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
142
fprintf(stderr, "Missing read buffer.\n");
145
fprintf(stderr, "Unknown.\n");
153
int w, h; /* width/height */
154
int number; /* number for multitexture binding */
155
int refcount; /* reference count */
156
GLenum target; /* GL_TEXTURE_* */
157
GLuint bindcode; /* opengl identifier for texture */
158
int fromblender; /* we got the texture from Blender */
160
GPUFrameBuffer *fb; /* GPUFramebuffer this texture is attached to */
161
int depth; /* is a depth texture? */
164
static unsigned char *GPU_texture_convert_pixels(int length, float *fpixels)
166
unsigned char *pixels, *p;
172
p = pixels = MEM_callocN(sizeof(unsigned char)*len, "GPUTexturePixels");
174
for (a=0; a<len; a++, p++, fp++)
180
static int is_pow2(int n)
182
return ((n)&(n-1))==0;
185
static int larger_pow2(int n)
196
static void GPU_glTexSubImageEmpty(GLenum target, GLenum format, int x, int y, int w, int h)
198
void *pixels = MEM_callocN(sizeof(char)*4*w*h, "GPUTextureEmptyPixels");
200
if (target == GL_TEXTURE_1D)
201
glTexSubImage1D(target, 0, x, w, format, GL_UNSIGNED_BYTE, pixels);
203
glTexSubImage2D(target, 0, x, y, w, h, format, GL_UNSIGNED_BYTE, pixels);
208
static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, int depth)
211
GLenum type, format, internalformat;
214
if(depth && !GLEW_ARB_depth_texture)
217
tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
222
tex->target = (n == 1)? GL_TEXTURE_1D: GL_TEXTURE_2D;
225
glGenTextures(1, &tex->bindcode);
227
if (!tex->bindcode) {
228
fprintf(stderr, "GPUTexture: texture create failed: %d\n",
230
GPU_texture_free(tex);
234
if (!GLEW_ARB_texture_non_power_of_two) {
235
tex->w = larger_pow2(tex->w);
236
tex->h = larger_pow2(tex->h);
240
glBindTexture(tex->target, tex->bindcode);
243
type = GL_UNSIGNED_BYTE;
244
format = GL_DEPTH_COMPONENT;
245
internalformat = GL_DEPTH_COMPONENT;
248
type = GL_UNSIGNED_BYTE;
250
internalformat = GL_RGBA8;
253
pixels = GPU_texture_convert_pixels(w*h, fpixels);
256
if (tex->target == GL_TEXTURE_1D) {
257
glTexImage1D(tex->target, 0, internalformat, tex->w, 0, format, type, 0);
260
glTexSubImage1D(tex->target, 0, 0, w, format, type,
261
pixels? pixels: fpixels);
264
GPU_glTexSubImageEmpty(tex->target, format, w, 0,
269
glTexImage2D(tex->target, 0, internalformat, tex->w, tex->h, 0,
273
glTexSubImage2D(tex->target, 0, 0, 0, w, h,
274
format, type, pixels? pixels: fpixels);
277
GPU_glTexSubImageEmpty(tex->target, format, w, 0, tex->w-w, tex->h);
279
GPU_glTexSubImageEmpty(tex->target, format, 0, h, w, tex->h-h);
287
glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
288
glTexParameteri(tex->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
289
glTexParameteri(tex->target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);
290
glTexParameteri(tex->target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
291
glTexParameteri(tex->target, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
294
glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
295
glTexParameteri(tex->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
298
if (tex->target != GL_TEXTURE_1D) {
299
/* CLAMP_TO_BORDER is an OpenGL 1.3 core feature */
300
GLenum wrapmode = (depth)? GL_CLAMP_TO_EDGE: GL_CLAMP_TO_BORDER;
301
glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, wrapmode);
302
glTexParameteri(tex->target, GL_TEXTURE_WRAP_T, wrapmode);
305
float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
306
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
310
glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
315
GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, double time)
318
GLint w, h, border, lastbindcode, bindcode;
320
glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastbindcode);
322
GPU_update_image_time(ima, time);
323
bindcode = GPU_verify_image(ima, 0, 0, 0);
325
if(ima->gputexture) {
326
ima->gputexture->bindcode = bindcode;
327
glBindTexture(GL_TEXTURE_2D, lastbindcode);
328
return ima->gputexture;
332
glBindTexture(GL_TEXTURE_2D, lastbindcode);
336
tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
337
tex->bindcode = bindcode;
340
tex->target = GL_TEXTURE_2D;
341
tex->fromblender = 1;
343
ima->gputexture= tex;
345
if (!glIsTexture(tex->bindcode)) {
346
GPU_print_error("Blender Texture");
349
glBindTexture(GL_TEXTURE_2D, tex->bindcode);
350
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
351
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
352
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BORDER, &border);
358
glBindTexture(GL_TEXTURE_2D, lastbindcode);
363
GPUTexture *GPU_texture_create_1D(int w, float *fpixels)
365
GPUTexture *tex = GPU_texture_create_nD(w, 1, 1, fpixels, 0);
368
GPU_texture_unbind(tex);
373
GPUTexture *GPU_texture_create_2D(int w, int h, float *fpixels)
375
GPUTexture *tex = GPU_texture_create_nD(w, h, 2, fpixels, 0);
378
GPU_texture_unbind(tex);
383
GPUTexture *GPU_texture_create_depth(int w, int h)
385
GPUTexture *tex = GPU_texture_create_nD(w, h, 2, NULL, 1);
388
GPU_texture_unbind(tex);
393
void GPU_texture_bind(GPUTexture *tex, int number)
397
if (number >= GG.maxtextures) {
398
GPU_print_error("Not enough texture slots.");
405
GPU_print_error("Pre Texture Bind");
407
arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + number);
408
if (number != 0) glActiveTextureARB(arbnumber);
409
glBindTexture(tex->target, tex->bindcode);
410
glEnable(tex->target);
411
if (number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
413
tex->number = number;
415
GPU_print_error("Post Texture Bind");
418
void GPU_texture_unbind(GPUTexture *tex)
422
if (tex->number >= GG.maxtextures) {
423
GPU_print_error("Not enough texture slots.");
427
if(tex->number == -1)
430
GPU_print_error("Pre Texture Unbind");
432
arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + tex->number);
433
if (tex->number != 0) glActiveTextureARB(arbnumber);
434
glBindTexture(tex->target, 0);
435
glDisable(tex->target);
436
if (tex->number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
440
GPU_print_error("Post Texture Unbind");
443
void GPU_texture_free(GPUTexture *tex)
447
if (tex->refcount < 0)
448
fprintf(stderr, "GPUTexture: negative refcount\n");
450
if (tex->refcount == 0) {
452
GPU_framebuffer_texture_detach(tex->fb, tex);
453
if (tex->bindcode && !tex->fromblender)
454
glDeleteTextures(1, &tex->bindcode);
460
void GPU_texture_ref(GPUTexture *tex)
465
int GPU_texture_target(GPUTexture *tex)
470
int GPU_texture_opengl_width(GPUTexture *tex)
475
int GPU_texture_opengl_height(GPUTexture *tex)
480
GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex)
487
struct GPUFrameBuffer {
489
GPUTexture *colortex;
490
GPUTexture *depthtex;
493
GPUFrameBuffer *GPU_framebuffer_create()
497
if (!GLEW_EXT_framebuffer_object)
500
fb= MEM_callocN(sizeof(GPUFrameBuffer), "GPUFrameBuffer");
501
glGenFramebuffersEXT(1, &fb->object);
504
fprintf(stderr, "GPUFFrameBuffer: framebuffer gen failed. %d\n",
506
GPU_framebuffer_free(fb);
513
int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex)
519
attachment = GL_DEPTH_ATTACHMENT_EXT;
521
attachment = GL_COLOR_ATTACHMENT0_EXT;
523
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
524
GG.currentfb = fb->object;
526
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment,
527
tex->target, tex->bindcode, 0);
530
glDrawBuffer(GL_NONE);
531
glReadBuffer(GL_NONE);
534
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
535
glReadBuffer(GL_NONE);
538
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
540
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
541
GPU_framebuffer_restore();
542
GPU_print_framebuffer_error(status);
556
void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex)
563
if(GG.currentfb != tex->fb->object) {
564
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tex->fb->object);
565
GG.currentfb = tex->fb->object;
570
attachment = GL_DEPTH_ATTACHMENT_EXT;
574
attachment = GL_COLOR_ATTACHMENT0_EXT;
577
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment,
583
void GPU_framebuffer_texture_bind(GPUFrameBuffer *fb, GPUTexture *tex)
585
/* push attributes */
586
glPushAttrib(GL_ENABLE_BIT);
587
glPushAttrib(GL_VIEWPORT_BIT);
588
glDisable(GL_SCISSOR_TEST);
590
/* bind framebuffer */
591
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tex->fb->object);
593
/* push matrices and set default viewport and matrix */
594
glViewport(0, 0, tex->w, tex->h);
595
GG.currentfb = tex->fb->object;
597
glMatrixMode(GL_PROJECTION);
600
glMatrixMode(GL_MODELVIEW);
605
void GPU_framebuffer_texture_unbind(GPUFrameBuffer *fb, GPUTexture *tex)
608
glMatrixMode(GL_PROJECTION);
610
glMatrixMode(GL_MODELVIEW);
613
/* restore attributes */
616
glEnable(GL_SCISSOR_TEST);
619
void GPU_framebuffer_free(GPUFrameBuffer *fb)
622
GPU_framebuffer_texture_detach(fb, fb->depthtex);
624
GPU_framebuffer_texture_detach(fb, fb->colortex);
627
glDeleteFramebuffersEXT(1, &fb->object);
629
if (GG.currentfb == fb->object) {
630
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
638
void GPU_framebuffer_restore()
640
if (GG.currentfb != 0) {
641
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
649
GLhandleARB object; /* handle for full shader */
650
GLhandleARB vertex; /* handle for vertex shader */
651
GLhandleARB fragment; /* handle for fragment shader */
652
GLhandleARB lib; /* handle for libment shader */
653
int totattrib; /* total number of attributes */
656
static void shader_print_errors(char *task, char *log, const char *code)
658
const char *c, *pos, *end = code + strlen(code);
661
fprintf(stderr, "GPUShader: %s error:\n", task);
665
while ((c < end) && (pos = strchr(c, '\n'))) {
666
fprintf(stderr, "%2d ", line);
667
fwrite(c, (pos+1)-c, 1, stderr);
672
fprintf(stderr, "%s", c);
675
fprintf(stderr, "%s\n", log);
678
GPUShader *GPU_shader_create(const char *vertexcode, const char *fragcode, /*GPUShader *lib,*/ const char *libcode)
682
const char *fragsource[2];
687
if (!GLEW_ARB_vertex_shader || !GLEW_ARB_fragment_shader)
690
shader = MEM_callocN(sizeof(GPUShader), "GPUShader");
693
shader->vertex = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
695
shader->fragment = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
696
shader->object = glCreateProgramObjectARB();
698
if (!shader->object ||
699
(vertexcode && !shader->vertex) ||
700
(fragcode && !shader->fragment)) {
701
fprintf(stderr, "GPUShader, object creation failed.\n");
702
GPU_shader_free(shader);
707
glAttachObjectARB(shader->object, shader->vertex);
708
glShaderSourceARB(shader->vertex, 1, (const char**)&vertexcode, NULL);
710
glCompileShaderARB(shader->vertex);
711
glGetObjectParameterivARB(shader->vertex, GL_OBJECT_COMPILE_STATUS_ARB, &status);
714
glGetInfoLogARB(shader->vertex, sizeof(log), &length, log);
715
shader_print_errors("compile", log, vertexcode);
717
GPU_shader_free(shader);
724
if(libcode) fragsource[count++] = libcode;
725
if(fragcode) fragsource[count++] = fragcode;
727
glAttachObjectARB(shader->object, shader->fragment);
728
glShaderSourceARB(shader->fragment, count, fragsource, NULL);
730
glCompileShaderARB(shader->fragment);
731
glGetObjectParameterivARB(shader->fragment, GL_OBJECT_COMPILE_STATUS_ARB, &status);
734
glGetInfoLogARB(shader->fragment, sizeof(log), &length, log);
735
shader_print_errors("compile", log, fragcode);
737
GPU_shader_free(shader);
742
/*if(lib && lib->lib)
743
glAttachObjectARB(shader->object, lib->lib);*/
745
glLinkProgramARB(shader->object);
746
glGetObjectParameterivARB(shader->object, GL_OBJECT_LINK_STATUS_ARB, &status);
748
glGetInfoLogARB(shader->object, sizeof(log), &length, log);
749
shader_print_errors("linking", log, fragcode);
751
GPU_shader_free(shader);
759
GPUShader *GPU_shader_create_lib(const char *code)
766
if (!GLEW_ARB_vertex_shader || !GLEW_ARB_fragment_shader)
769
shader = MEM_callocN(sizeof(GPUShader), "GPUShader");
771
shader->lib = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
774
fprintf(stderr, "GPUShader, object creation failed.\n");
775
GPU_shader_free(shader);
779
glShaderSourceARB(shader->lib, 1, (const char**)&code, NULL);
781
glCompileShaderARB(shader->lib);
782
glGetObjectParameterivARB(shader->lib, GL_OBJECT_COMPILE_STATUS_ARB, &status);
785
glGetInfoLogARB(shader->lib, sizeof(log), &length, log);
786
shader_print_errors("compile", log, code);
788
GPU_shader_free(shader);
796
void GPU_shader_bind(GPUShader *shader)
798
GPU_print_error("Pre Shader Bind");
799
glUseProgramObjectARB(shader->object);
800
GPU_print_error("Post Shader Bind");
803
void GPU_shader_unbind()
805
GPU_print_error("Pre Shader Unbind");
806
glUseProgramObjectARB(0);
807
GPU_print_error("Post Shader Unbind");
810
void GPU_shader_free(GPUShader *shader)
813
glDeleteObjectARB(shader->lib);
815
glDeleteObjectARB(shader->vertex);
816
if (shader->fragment)
817
glDeleteObjectARB(shader->fragment);
819
glDeleteObjectARB(shader->object);
823
int GPU_shader_get_uniform(GPUShader *shader, char *name)
825
return glGetUniformLocationARB(shader->object, name);
828
void GPU_shader_uniform_vector(GPUShader *shader, int location, int length, int arraysize, float *value)
833
GPU_print_error("Pre Uniform Vector");
835
if (length == 1) glUniform1fvARB(location, arraysize, value);
836
else if (length == 2) glUniform2fvARB(location, arraysize, value);
837
else if (length == 3) glUniform3fvARB(location, arraysize, value);
838
else if (length == 4) glUniform4fvARB(location, arraysize, value);
839
else if (length == 9) glUniformMatrix3fvARB(location, arraysize, 0, value);
840
else if (length == 16) glUniformMatrix4fvARB(location, arraysize, 0, value);
842
GPU_print_error("Post Uniform Vector");
845
void GPU_shader_uniform_texture(GPUShader *shader, int location, GPUTexture *tex)
849
if (tex->number >= GG.maxtextures) {
850
GPU_print_error("Not enough texture slots.");
854
if(tex->number == -1)
860
GPU_print_error("Pre Uniform Texture");
862
arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + tex->number);
864
if (tex->number != 0) glActiveTextureARB(arbnumber);
865
glBindTexture(tex->target, tex->bindcode);
866
glUniform1iARB(location, tex->number);
867
glEnable(tex->target);
868
if (tex->number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
870
GPU_print_error("Post Uniform Texture");
873
int GPU_shader_get_attribute(GPUShader *shader, char *name)
877
GPU_print_error("Pre Get Attribute");
879
index = glGetAttribLocationARB(shader->object, name);
881
GPU_print_error("Post Get Attribute");
889
typedef struct GPUPixelBuffer {
897
void GPU_pixelbuffer_free(GPUPixelBuffer *pb)
900
glDeleteBuffersARB(pb->numbuffers, pb->bindcode);
904
GPUPixelBuffer *gpu_pixelbuffer_create(int x, int y, int halffloat, int numbuffers)
908
if (!GLEW_ARB_multitexture || !GLEW_EXT_pixel_buffer_object)
911
pb = MEM_callocN(sizeof(GPUPixelBuffer), "GPUPBO");
912
pb->datasize = x*y*4*((halffloat)? 16: 8);
913
pb->numbuffers = numbuffers;
914
pb->halffloat = halffloat;
916
glGenBuffersARB(pb->numbuffers, pb->bindcode);
918
if (!pb->bindcode[0]) {
919
fprintf(stderr, "GPUPixelBuffer allocation failed\n");
920
GPU_pixelbuffer_free(pb);
927
void GPU_pixelbuffer_texture(GPUTexture *tex, GPUPixelBuffer *pb)
932
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, tex->bindcode);
934
for (i = 0; i < pb->numbuffers; i++) {
935
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pb->bindcode[pb->current]);
936
glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, pb->datasize, NULL,
939
pixels = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY);
940
/*memcpy(pixels, _oImage.data(), pb->datasize);*/
942
if (!glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT)) {
943
fprintf(stderr, "Could not unmap opengl PBO\n");
948
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
951
static int pixelbuffer_map_into_gpu(GLuint bindcode)
955
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, bindcode);
956
pixels = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY);
958
/* do stuff in pixels */
960
if (!glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT)) {
961
fprintf(stderr, "Could not unmap opengl PBO\n");
968
static void pixelbuffer_copy_to_texture(GPUTexture *tex, GPUPixelBuffer *pb, GLuint bindcode)
970
GLenum type = (pb->halffloat)? GL_HALF_FLOAT_NV: GL_UNSIGNED_BYTE;
971
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, tex->bindcode);
972
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, bindcode);
974
glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, tex->w, tex->h,
975
GL_RGBA, type, NULL);
977
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
978
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
981
void GPU_pixelbuffer_async_to_gpu(GPUTexture *tex, GPUPixelBuffer *pb)
985
if (pb->numbuffers == 1) {
986
pixelbuffer_copy_to_texture(tex, pb, pb->bindcode[0]);
987
pixelbuffer_map_into_gpu(pb->bindcode[0]);
990
pb->current = (pb->current+1)%pb->numbuffers;
991
newbuffer = (pb->current+1)%pb->numbuffers;
993
pixelbuffer_map_into_gpu(pb->bindcode[newbuffer]);
994
pixelbuffer_copy_to_texture(tex, pb, pb->bindcode[pb->current]);