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);
316 GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels)
319 GLenum type, format, internalformat;
321 float vfBorderColor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
323 tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
329 tex->target = GL_TEXTURE_3D;
331 glGenTextures(1, &tex->bindcode);
333 if (!tex->bindcode) {
334 fprintf(stderr, "GPUTexture: texture create failed: %d\n",
336 GPU_texture_free(tex);
340 if (!GLEW_ARB_texture_non_power_of_two)
342 tex->w = larger_pow2(tex->w);
343 tex->h = larger_pow2(tex->h);
344 tex->depth = larger_pow2(tex->depth);
348 glBindTexture(tex->target, tex->bindcode);
350 type = GL_UNSIGNED_BYTE;
352 internalformat = GL_RGBA8;
355 pixels = GPU_texture_convert_pixels(w*h*depth, fpixels);
357 glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, 0);
360 glTexSubImage3D(tex->target, 0, 0, 0, 0, w, h, depth, format, type, pixels);
363 glTexParameterfv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, vfBorderColor);
364 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
365 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
366 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
367 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
368 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
374 GPU_texture_unbind(tex);
379 GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, double time, int mipmap)
382 GLint w, h, border, lastbindcode, bindcode;
384 glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastbindcode);
386 GPU_update_image_time(ima, time);
387 bindcode = GPU_verify_image(ima, 0, 0, 0, mipmap);
389 if(ima->gputexture) {
390 ima->gputexture->bindcode = bindcode;
391 glBindTexture(GL_TEXTURE_2D, lastbindcode);
392 return ima->gputexture;
396 glBindTexture(GL_TEXTURE_2D, lastbindcode);
400 tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
401 tex->bindcode = bindcode;
404 tex->target = GL_TEXTURE_2D;
405 tex->fromblender = 1;
407 ima->gputexture= tex;
409 if (!glIsTexture(tex->bindcode)) {
410 GPU_print_error("Blender Texture");
413 glBindTexture(GL_TEXTURE_2D, tex->bindcode);
414 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
415 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
416 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BORDER, &border);
422 glBindTexture(GL_TEXTURE_2D, lastbindcode);
427 GPUTexture *GPU_texture_create_1D(int w, float *fpixels)
429 GPUTexture *tex = GPU_texture_create_nD(w, 1, 1, fpixels, 0);
432 GPU_texture_unbind(tex);
437 GPUTexture *GPU_texture_create_2D(int w, int h, float *fpixels)
439 GPUTexture *tex = GPU_texture_create_nD(w, h, 2, fpixels, 0);
442 GPU_texture_unbind(tex);
447 GPUTexture *GPU_texture_create_depth(int w, int h)
449 GPUTexture *tex = GPU_texture_create_nD(w, h, 2, NULL, 1);
452 GPU_texture_unbind(tex);
457 void GPU_texture_bind(GPUTexture *tex, int number)
461 if (number >= GG.maxtextures) {
462 GPU_print_error("Not enough texture slots.");
469 GPU_print_error("Pre Texture Bind");
471 arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + number);
472 if (number != 0) glActiveTextureARB(arbnumber);
473 glBindTexture(tex->target, tex->bindcode);
474 glEnable(tex->target);
475 if (number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
477 tex->number = number;
479 GPU_print_error("Post Texture Bind");
482 void GPU_texture_unbind(GPUTexture *tex)
486 if (tex->number >= GG.maxtextures) {
487 GPU_print_error("Not enough texture slots.");
491 if(tex->number == -1)
494 GPU_print_error("Pre Texture Unbind");
496 arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + tex->number);
497 if (tex->number != 0) glActiveTextureARB(arbnumber);
498 glBindTexture(tex->target, 0);
499 glDisable(tex->target);
500 if (tex->number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
504 GPU_print_error("Post Texture Unbind");
507 void GPU_texture_free(GPUTexture *tex)
511 if (tex->refcount < 0)
512 fprintf(stderr, "GPUTexture: negative refcount\n");
514 if (tex->refcount == 0) {
516 GPU_framebuffer_texture_detach(tex->fb, tex);
517 if (tex->bindcode && !tex->fromblender)
518 glDeleteTextures(1, &tex->bindcode);
524 void GPU_texture_ref(GPUTexture *tex)
529 int GPU_texture_target(GPUTexture *tex)
534 int GPU_texture_opengl_width(GPUTexture *tex)
539 int GPU_texture_opengl_height(GPUTexture *tex)
544 GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex)
551 struct GPUFrameBuffer {
553 GPUTexture *colortex;
554 GPUTexture *depthtex;
557 GPUFrameBuffer *GPU_framebuffer_create()
561 if (!GLEW_EXT_framebuffer_object)
564 fb= MEM_callocN(sizeof(GPUFrameBuffer), "GPUFrameBuffer");
565 glGenFramebuffersEXT(1, &fb->object);
568 fprintf(stderr, "GPUFFrameBuffer: framebuffer gen failed. %d\n",
570 GPU_framebuffer_free(fb);
577 int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex)
583 attachment = GL_DEPTH_ATTACHMENT_EXT;
585 attachment = GL_COLOR_ATTACHMENT0_EXT;
587 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
588 GG.currentfb = fb->object;
590 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment,
591 tex->target, tex->bindcode, 0);
594 glDrawBuffer(GL_NONE);
595 glReadBuffer(GL_NONE);
598 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
599 glReadBuffer(GL_NONE);
602 status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
604 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
605 GPU_framebuffer_restore();
606 GPU_print_framebuffer_error(status);
620 void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex)
627 if(GG.currentfb != tex->fb->object) {
628 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tex->fb->object);
629 GG.currentfb = tex->fb->object;
634 attachment = GL_DEPTH_ATTACHMENT_EXT;
638 attachment = GL_COLOR_ATTACHMENT0_EXT;
641 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment,
647 void GPU_framebuffer_texture_bind(GPUFrameBuffer *fb, GPUTexture *tex)
649 /* push attributes */
650 glPushAttrib(GL_ENABLE_BIT);
651 glPushAttrib(GL_VIEWPORT_BIT);
652 glDisable(GL_SCISSOR_TEST);
654 /* bind framebuffer */
655 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tex->fb->object);
657 /* push matrices and set default viewport and matrix */
658 glViewport(0, 0, tex->w, tex->h);
659 GG.currentfb = tex->fb->object;
661 glMatrixMode(GL_PROJECTION);
664 glMatrixMode(GL_MODELVIEW);
669 void GPU_framebuffer_texture_unbind(GPUFrameBuffer *fb, GPUTexture *tex)
672 glMatrixMode(GL_PROJECTION);
674 glMatrixMode(GL_MODELVIEW);
677 /* restore attributes */
680 glEnable(GL_SCISSOR_TEST);
683 void GPU_framebuffer_free(GPUFrameBuffer *fb)
686 GPU_framebuffer_texture_detach(fb, fb->depthtex);
688 GPU_framebuffer_texture_detach(fb, fb->colortex);
691 glDeleteFramebuffersEXT(1, &fb->object);
693 if (GG.currentfb == fb->object) {
694 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
702 void GPU_framebuffer_restore()
704 if (GG.currentfb != 0) {
705 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
713 GLhandleARB object; /* handle for full shader */
714 GLhandleARB vertex; /* handle for vertex shader */
715 GLhandleARB fragment; /* handle for fragment shader */
716 GLhandleARB lib; /* handle for libment shader */
717 int totattrib; /* total number of attributes */
720 static void shader_print_errors(char *task, char *log, const char *code)
722 const char *c, *pos, *end = code + strlen(code);
725 fprintf(stderr, "GPUShader: %s error:\n", task);
729 while ((c < end) && (pos = strchr(c, '\n'))) {
730 fprintf(stderr, "%2d ", line);
731 fwrite(c, (pos+1)-c, 1, stderr);
736 fprintf(stderr, "%s", c);
739 fprintf(stderr, "%s\n", log);
742 GPUShader *GPU_shader_create(const char *vertexcode, const char *fragcode, /*GPUShader *lib,*/ const char *libcode)
746 const char *fragsource[2];
751 if (!GLEW_ARB_vertex_shader || !GLEW_ARB_fragment_shader)
754 shader = MEM_callocN(sizeof(GPUShader), "GPUShader");
757 shader->vertex = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
759 shader->fragment = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
760 shader->object = glCreateProgramObjectARB();
762 if (!shader->object ||
763 (vertexcode && !shader->vertex) ||
764 (fragcode && !shader->fragment)) {
765 fprintf(stderr, "GPUShader, object creation failed.\n");
766 GPU_shader_free(shader);
771 glAttachObjectARB(shader->object, shader->vertex);
772 glShaderSourceARB(shader->vertex, 1, (const char**)&vertexcode, NULL);
774 glCompileShaderARB(shader->vertex);
775 glGetObjectParameterivARB(shader->vertex, GL_OBJECT_COMPILE_STATUS_ARB, &status);
778 glGetInfoLogARB(shader->vertex, sizeof(log), &length, log);
779 shader_print_errors("compile", log, vertexcode);
781 GPU_shader_free(shader);
788 if(libcode) fragsource[count++] = libcode;
789 if(fragcode) fragsource[count++] = fragcode;
791 glAttachObjectARB(shader->object, shader->fragment);
792 glShaderSourceARB(shader->fragment, count, fragsource, NULL);
794 glCompileShaderARB(shader->fragment);
795 glGetObjectParameterivARB(shader->fragment, GL_OBJECT_COMPILE_STATUS_ARB, &status);
798 glGetInfoLogARB(shader->fragment, sizeof(log), &length, log);
799 shader_print_errors("compile", log, fragcode);
801 GPU_shader_free(shader);
806 /*if(lib && lib->lib)
807 glAttachObjectARB(shader->object, lib->lib);*/
809 glLinkProgramARB(shader->object);
810 glGetObjectParameterivARB(shader->object, GL_OBJECT_LINK_STATUS_ARB, &status);
812 glGetInfoLogARB(shader->object, sizeof(log), &length, log);
813 if (fragcode) shader_print_errors("linking", log, fragcode);
814 else if (vertexcode) shader_print_errors("linking", log, vertexcode);
815 else if (libcode) shader_print_errors("linking", log, libcode);
817 GPU_shader_free(shader);
825 GPUShader *GPU_shader_create_lib(const char *code)
832 if (!GLEW_ARB_vertex_shader || !GLEW_ARB_fragment_shader)
835 shader = MEM_callocN(sizeof(GPUShader), "GPUShader");
837 shader->lib = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
840 fprintf(stderr, "GPUShader, object creation failed.\n");
841 GPU_shader_free(shader);
845 glShaderSourceARB(shader->lib, 1, (const char**)&code, NULL);
847 glCompileShaderARB(shader->lib);
848 glGetObjectParameterivARB(shader->lib, GL_OBJECT_COMPILE_STATUS_ARB, &status);
851 glGetInfoLogARB(shader->lib, sizeof(log), &length, log);
852 shader_print_errors("compile", log, code);
854 GPU_shader_free(shader);
862 void GPU_shader_bind(GPUShader *shader)
864 GPU_print_error("Pre Shader Bind");
865 glUseProgramObjectARB(shader->object);
866 GPU_print_error("Post Shader Bind");
869 void GPU_shader_unbind()
871 GPU_print_error("Pre Shader Unbind");
872 glUseProgramObjectARB(0);
873 GPU_print_error("Post Shader Unbind");
876 void GPU_shader_free(GPUShader *shader)
879 glDeleteObjectARB(shader->lib);
881 glDeleteObjectARB(shader->vertex);
882 if (shader->fragment)
883 glDeleteObjectARB(shader->fragment);
885 glDeleteObjectARB(shader->object);
889 int GPU_shader_get_uniform(GPUShader *shader, char *name)
891 return glGetUniformLocationARB(shader->object, name);
894 void GPU_shader_uniform_vector(GPUShader *shader, int location, int length, int arraysize, float *value)
899 GPU_print_error("Pre Uniform Vector");
901 if (length == 1) glUniform1fvARB(location, arraysize, value);
902 else if (length == 2) glUniform2fvARB(location, arraysize, value);
903 else if (length == 3) glUniform3fvARB(location, arraysize, value);
904 else if (length == 4) glUniform4fvARB(location, arraysize, value);
905 else if (length == 9) glUniformMatrix3fvARB(location, arraysize, 0, value);
906 else if (length == 16) glUniformMatrix4fvARB(location, arraysize, 0, value);
908 GPU_print_error("Post Uniform Vector");
911 void GPU_shader_uniform_texture(GPUShader *shader, int location, GPUTexture *tex)
915 if (tex->number >= GG.maxtextures) {
916 GPU_print_error("Not enough texture slots.");
920 if(tex->number == -1)
926 GPU_print_error("Pre Uniform Texture");
928 arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + tex->number);
930 if (tex->number != 0) glActiveTextureARB(arbnumber);
931 glBindTexture(tex->target, tex->bindcode);
932 glUniform1iARB(location, tex->number);
933 glEnable(tex->target);
934 if (tex->number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
936 GPU_print_error("Post Uniform Texture");
939 int GPU_shader_get_attribute(GPUShader *shader, char *name)
943 GPU_print_error("Pre Get Attribute");
945 index = glGetAttribLocationARB(shader->object, name);
947 GPU_print_error("Post Get Attribute");
955 typedef struct GPUPixelBuffer {
963 void GPU_pixelbuffer_free(GPUPixelBuffer *pb)
966 glDeleteBuffersARB(pb->numbuffers, pb->bindcode);
970 GPUPixelBuffer *gpu_pixelbuffer_create(int x, int y, int halffloat, int numbuffers)
974 if (!GLEW_ARB_multitexture || !GLEW_EXT_pixel_buffer_object)
977 pb = MEM_callocN(sizeof(GPUPixelBuffer), "GPUPBO");
978 pb->datasize = x*y*4*((halffloat)? 16: 8);
979 pb->numbuffers = numbuffers;
980 pb->halffloat = halffloat;
982 glGenBuffersARB(pb->numbuffers, pb->bindcode);
984 if (!pb->bindcode[0]) {
985 fprintf(stderr, "GPUPixelBuffer allocation failed\n");
986 GPU_pixelbuffer_free(pb);
993 void GPU_pixelbuffer_texture(GPUTexture *tex, GPUPixelBuffer *pb)
998 glBindTexture(GL_TEXTURE_RECTANGLE_EXT, tex->bindcode);
1000 for (i = 0; i < pb->numbuffers; i++) {
1001 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pb->bindcode[pb->current]);
1002 glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, pb->datasize, NULL,
1003 GL_STREAM_DRAW_ARB);
1005 pixels = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY);
1006 /*memcpy(pixels, _oImage.data(), pb->datasize);*/
1008 if (!glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT)) {
1009 fprintf(stderr, "Could not unmap opengl PBO\n");
1014 glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
1017 static int pixelbuffer_map_into_gpu(GLuint bindcode)
1021 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, bindcode);
1022 pixels = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY);
1024 /* do stuff in pixels */
1026 if (!glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT)) {
1027 fprintf(stderr, "Could not unmap opengl PBO\n");
1034 static void pixelbuffer_copy_to_texture(GPUTexture *tex, GPUPixelBuffer *pb, GLuint bindcode)
1036 GLenum type = (pb->halffloat)? GL_HALF_FLOAT_NV: GL_UNSIGNED_BYTE;
1037 glBindTexture(GL_TEXTURE_RECTANGLE_EXT, tex->bindcode);
1038 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, bindcode);
1040 glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, tex->w, tex->h,
1041 GL_RGBA, type, NULL);
1043 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
1044 glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
1047 void GPU_pixelbuffer_async_to_gpu(GPUTexture *tex, GPUPixelBuffer *pb)
1051 if (pb->numbuffers == 1) {
1052 pixelbuffer_copy_to_texture(tex, pb, pb->bindcode[0]);
1053 pixelbuffer_map_into_gpu(pb->bindcode[0]);
1056 pb->current = (pb->current+1)%pb->numbuffers;
1057 newbuffer = (pb->current+1)%pb->numbuffers;
1059 pixelbuffer_map_into_gpu(pb->bindcode[newbuffer]);
1060 pixelbuffer_copy_to_texture(tex, pb, pb->bindcode[pb->current]);