Commit: 90761e3e754221d8c54c175e60c1731f3f4e5ba2
Author: Lukas Tönne
Date:   Wed Jun 29 17:23:32 2016 +0200
Branches: strand_gpu
https://developer.blender.org/rB90761e3e754221d8c54c175e60c1731f3f4e5ba2

Skeleton GPU code for creating a special hair shader.

This will include a geometry shader as well as vertex/fragment shaders,
for efficiently generating strand geometry based on control strands.

===================================================================

M       source/blender/blenkernel/BKE_strands.h
M       source/blender/blenkernel/intern/strands.c
M       source/blender/blenloader/intern/readfile.c
M       source/blender/editors/space_view3d/drawobject.c
M       source/blender/gpu/CMakeLists.txt
A       source/blender/gpu/GPU_strands.h
A       source/blender/gpu/intern/gpu_strands.c
M       source/blender/makesdna/DNA_strand_types.h

===================================================================

diff --git a/source/blender/blenkernel/BKE_strands.h 
b/source/blender/blenkernel/BKE_strands.h
index 9e329fb..2ecdaf8 100644
--- a/source/blender/blenkernel/BKE_strands.h
+++ b/source/blender/blenkernel/BKE_strands.h
@@ -37,6 +37,7 @@
 #include "DNA_strand_types.h"
 
 struct DerivedMesh;
+struct GPUStrands;
 
 static const unsigned int STRAND_INDEX_NONE = 0xFFFFFFFF;
 
diff --git a/source/blender/blenkernel/intern/strands.c 
b/source/blender/blenkernel/intern/strands.c
index b699825..b86421d 100644
--- a/source/blender/blenkernel/intern/strands.c
+++ b/source/blender/blenkernel/intern/strands.c
@@ -38,6 +38,8 @@
 #include "BKE_mesh_sample.h"
 #include "BKE_strands.h"
 
+#include "GPU_strands.h"
+
 Strands *BKE_strands_new(void)
 {
        Strands *strands = MEM_callocN(sizeof(Strands), "strands");
@@ -52,11 +54,17 @@ Strands *BKE_strands_copy(Strands *strands)
                nstrands->controls = MEM_dupallocN(strands->controls);
        }
        
+       /* lazy initialized */
+       nstrands->gpu_strands = NULL;
+       
        return nstrands;
 }
 
 void BKE_strands_free(Strands *strands)
 {
+       if (strands->gpu_strands)
+               GPU_strands_free(strands->gpu_strands);
+       
        MEM_freeN(strands);
 }
 
diff --git a/source/blender/blenloader/intern/readfile.c 
b/source/blender/blenloader/intern/readfile.c
index 7fc0d1c..3f1c736 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -4309,6 +4309,9 @@ static void direct_link_strands(FileData *fd, Strands 
*strands)
                return;
        
        strands->controls = newdataadr(fd, strands->controls);
+       
+       /* runtime */
+       strands->gpu_strands = NULL;
 }
 
 /* ************ READ MESH ***************** */
diff --git a/source/blender/editors/space_view3d/drawobject.c 
b/source/blender/editors/space_view3d/drawobject.c
index 7156668..8c0e05e 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -90,6 +90,7 @@
 #include "GPU_select.h"
 #include "GPU_basic_shader.h"
 #include "GPU_shader.h"
+#include "GPU_strands.h"
 
 #include "ED_mesh.h"
 #include "ED_particle.h"
@@ -7467,7 +7468,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, 
Base *base, const short
        const bool is_picking = (G.f & G_PICKSEL) != 0;
        const bool has_particles = (ob->particlesystem.first != NULL);
        bool skip_object = false;  /* Draw particles but not their emitter 
object. */
-       SmokeModifierData *smd = NULL;
+       SmokeModifierData *smoke_md = NULL;
 
        if (ob != scene->obedit) {
                if (ob->restrictflag & OB_RESTRICT_VIEW)
@@ -7506,9 +7507,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, 
Base *base, const short
            (md = modifiers_findByType(ob, eModifierType_Smoke)) &&
            (modifier_isEnabled(scene, md, eModifierMode_Realtime)))
        {
-               smd = (SmokeModifierData *)md;
+               smoke_md = (SmokeModifierData *)md;
 
-               if (smd->domain) {
+               if (smoke_md->domain) {
                        if (!v3d->transp && (dflag & DRAW_PICKING) == 0) {
                                if (!v3d->xray && !(ob->dtx & OB_DRAWXRAY)) {
                                        /* object has already been drawn so 
skip drawing it */
@@ -7846,7 +7847,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, 
Base *base, const short
        }
 
        /* draw code for smoke */
-       if (smd) {
+       if (smoke_md) {
 #if 0
                /* draw collision objects */
                if ((smd->type & MOD_SMOKE_TYPE_COLL) && smd->coll) {
@@ -7880,8 +7881,8 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, 
Base *base, const short
 #endif
 
                /* only draw domains */
-               if (smd->domain) {
-                       SmokeDomainSettings *sds = smd->domain;
+               if (smoke_md->domain) {
+                       SmokeDomainSettings *sds = smoke_md->domain;
                        float viewnormal[3];
 
                        glLoadMatrixf(rv3d->viewmat);
@@ -7942,15 +7943,15 @@ void draw_object(Scene *scene, ARegion *ar, View3D 
*v3d, Base *base, const short
 
                                if (!sds->wt || !(sds->viewsettings & 
MOD_SMOKE_VIEW_SHOWBIG)) {
                                        sds->tex = NULL;
-                                       GPU_create_smoke(smd, 0);
+                                       GPU_create_smoke(smoke_md, 0);
                                        draw_smoke_volume(sds, ob, p0, p1, 
viewnormal);
-                                       GPU_free_smoke(smd);
+                                       GPU_free_smoke(smoke_md);
                                }
                                else if (sds->wt && (sds->viewsettings & 
MOD_SMOKE_VIEW_SHOWBIG)) {
                                        sds->tex = NULL;
-                                       GPU_create_smoke(smd, 1);
+                                       GPU_create_smoke(smoke_md, 1);
                                        draw_smoke_volume(sds, ob, p0, p1, 
viewnormal);
-                                       GPU_free_smoke(smd);
+                                       GPU_free_smoke(smoke_md);
                                }
 
                                /* smoke debug render */
@@ -7964,6 +7965,45 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, 
Base *base, const short
                }
        }
 
+       /* strands drawing */
+       for (md = ob->modifiers.first; md; md = md->next) {
+               if (md->type == eModifierType_Strands) {
+                       StrandsModifierData *smd = (StrandsModifierData *)md;
+                       
+                       if (smd->strands) {
+                               GPUStrands *gpu_strands = 
GPU_strands_get(smd->strands);
+                               
+                               GPU_strands_bind_uniforms(gpu_strands, 
ob->obmat, rv3d->viewmat);
+                               GPU_strands_bind(gpu_strands, rv3d->viewmat, 
rv3d->viewinv);
+                               
+                               GLuint vertex_buffer;
+                               glGenBuffers(1, &vertex_buffer);
+                               glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
+                               const size_t numverts = 4;
+                               float verts[12] = {
+                                   0.0f, 0.0f, 0.0f,
+                                   1.0f, 0.0f, 0.0f,
+                                   0.0f, 1.0f, 0.0f,
+                                   1.0f, 1.0f, 0.0f,
+                               };
+                               glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 
* numverts, verts, GL_STATIC_DRAW);
+                       
+                               glEnableClientState(GL_VERTEX_ARRAY);
+                               glVertexPointer(3, GL_FLOAT, 0, NULL);
+                       
+                               glDrawArrays(GL_TRIANGLES, 0, numverts);
+                       
+                               glDisableClientState(GL_VERTEX_ARRAY);
+                       
+                               /* cleanup */
+                               glBindBuffer(GL_ARRAY_BUFFER, 0);
+                               glDeleteBuffers(1, &vertex_buffer);
+                               
+                               GPU_strands_unbind(gpu_strands);
+                       }
+               }
+       }
+
        if (!render_override) {
                bConstraint *con;
 
diff --git a/source/blender/gpu/CMakeLists.txt 
b/source/blender/gpu/CMakeLists.txt
index cfa0831..c3cf5d3 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -58,6 +58,7 @@ set(SRC
        intern/gpu_material.c
        intern/gpu_select.c
        intern/gpu_shader.c
+       intern/gpu_strands.c
        intern/gpu_texture.c
 
        shaders/gpu_shader_fx_lib.glsl
@@ -93,6 +94,7 @@ set(SRC
        GPU_material.h
        GPU_select.h
        GPU_shader.h
+       GPU_strands.h
        GPU_texture.h
        intern/gpu_codegen.h
        intern/gpu_private.h
diff --git a/source/blender/gpu/GPU_strands.h b/source/blender/gpu/GPU_strands.h
new file mode 100644
index 0000000..7d73b38
--- /dev/null
+++ b/source/blender/gpu/GPU_strands.h
@@ -0,0 +1,60 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file GPU_strands.h
+ *  \ingroup gpu
+ */
+
+#ifndef __GPU_STRANDS_H__
+#define __GPU_STRANDS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct Strands;
+
+typedef struct GPUStrands GPUStrands;
+
+GPUStrands *GPU_strands_get(struct Strands *strands);
+
+void GPU_strands_free(struct GPUStrands *gpu_strands);
+
+void GPU_strands_bind(
+        GPUStrands *gpu_strands,
+        float viewmat[4][4], float viewinv[4][4]);
+void GPU_strands_bind_uniforms(
+        GPUStrands *gpu_strands,
+        float obmat[4][4], float viewmat[4][4]);
+void GPU_strands_unbind(GPUStrands *gpu_strands);
+bool GPU_strands_bound(GPUStrands *gpu_strands);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__GPU_MATERIAL_H__*/
diff --git a/source/blender/gpu/intern/gpu_strands.c 
b/source/blender/gpu/intern/gpu_strands.c
new file mode 100644
index 0000000..2bf71d3
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_strands.c
@@ -0,0 +1,198 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/gpu/intern/gpu_strands.c
+ *  \ingroup gpu
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_dynstr.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+#include "BLI_string.h"
+
+#include "DNA_strand_types.h"
+
+#include "BKE_strands.h"
+
+#include "GPU_extensions.h"
+#include "GPU_strands.h"
+#include "GPU_shader.h"
+
+struct GPUStrands {
+       bool bound;
+       
+       GPUShader *shader;
+       
+       char *fragmentcode;
+       char *geometrycode;
+       char *vertexcode;
+};
+
+extern char datatoc_gpu_shader_basic_vert_glsl[];
+extern char datatoc_gpu_shader_basic_frag_glsl[];
+extern char datatoc_gpu_shader_basic_geom_glsl[];
+
+static char *codegen_vertex(void)
+{
+#if 0
+       char *code;
+       
+       DynStr *ds = BLI_dynstr_new();
+       
+       code = BLI_dynstr_get_cstring(ds);
+       BLI_dynstr_free(ds);
+       
+       return code;
+#else
+       return BLI_strdup(datatoc_gpu_shader_basic_vert_glsl);
+#endif
+}
+
+static char *codege

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to