mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
[spline/bezier]Fix compatibility for GLES.
This commit is contained in:
parent
a1ec735f6c
commit
0e6c2b00cf
3 changed files with 126 additions and 65 deletions
|
@ -148,7 +148,7 @@ DrawEngineGLES::DrawEngineGLES()
|
|||
InitDeviceObjects();
|
||||
register_gl_resource_holder(this);
|
||||
|
||||
tessDataTransfer = new TessellationDataTransferGLES();
|
||||
tessDataTransfer = new TessellationDataTransferGLES(!gl_extensions.IsGLES && gl_extensions.VersionGEThan(3, 0, 0));
|
||||
}
|
||||
|
||||
DrawEngineGLES::~DrawEngineGLES() {
|
||||
|
@ -1119,54 +1119,96 @@ bool DrawEngineGLES::IsCodePtrVertexDecoder(const u8 *ptr) const {
|
|||
}
|
||||
|
||||
void DrawEngineGLES::TessellationDataTransferGLES::SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) {
|
||||
#ifdef USING_GLES2
|
||||
#define GL_TEXTURE_1D GL_TEXTURE_2D
|
||||
#define glTexImage1D(t, l, ifmt, w, br, fmt, type, p) glTexImage2D(t, l, ifmt, w, 1, br, fmt, type, p)
|
||||
#define glTexSubImage1D(t, l, xo, w, fmt, type, p) glTexSubImage2D(t, l, xo, 0, w, 1, fmt, type, p)
|
||||
#endif
|
||||
// Position
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_1D, data_tex[0]);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
if (prevSize < size) {
|
||||
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB32F, size, 0, GL_RGB, GL_FLOAT, (GLfloat*)pos);
|
||||
prevSize = size;
|
||||
} else {
|
||||
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, size, GL_RGB, GL_FLOAT, (GLfloat*)pos);
|
||||
}
|
||||
|
||||
// Texcoords
|
||||
if (hasTexCoords) {
|
||||
glActiveTexture(GL_TEXTURE4);
|
||||
glBindTexture(GL_TEXTURE_1D, data_tex[1]);
|
||||
if (isAllowTexture1D) {
|
||||
// Position
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_1D, data_tex[0]);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
if (prevSizeTex < size) {
|
||||
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB32F, size, 0, GL_RGB, GL_FLOAT, (GLfloat*)tex);
|
||||
prevSizeTex = size;
|
||||
if (prevSize < size) {
|
||||
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB32F, size, 0, GL_RGB, GL_FLOAT, (GLfloat*)pos);
|
||||
prevSize = size;
|
||||
} else {
|
||||
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, size, GL_RGB, GL_FLOAT, (GLfloat*)tex);
|
||||
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, size, GL_RGB, GL_FLOAT, (GLfloat*)pos);
|
||||
}
|
||||
}
|
||||
|
||||
// Color
|
||||
glActiveTexture(GL_TEXTURE5);
|
||||
glBindTexture(GL_TEXTURE_1D, data_tex[2]);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
int sizeColor = hasColor ? size : 1;
|
||||
if (prevSizeCol < sizeColor) {
|
||||
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, sizeColor, 0, GL_RGBA, GL_FLOAT, (GLfloat*)col);
|
||||
prevSizeCol = sizeColor;
|
||||
// Texcoords
|
||||
if (hasTexCoords) {
|
||||
glActiveTexture(GL_TEXTURE4);
|
||||
glBindTexture(GL_TEXTURE_1D, data_tex[1]);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
if (prevSizeTex < size) {
|
||||
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB32F, size, 0, GL_RGB, GL_FLOAT, (GLfloat*)tex);
|
||||
prevSizeTex = size;
|
||||
} else {
|
||||
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, size, GL_RGB, GL_FLOAT, (GLfloat*)tex);
|
||||
}
|
||||
}
|
||||
|
||||
// Color
|
||||
glActiveTexture(GL_TEXTURE5);
|
||||
glBindTexture(GL_TEXTURE_1D, data_tex[2]);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
int sizeColor = hasColor ? size : 1;
|
||||
if (prevSizeCol < sizeColor) {
|
||||
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, sizeColor, 0, GL_RGBA, GL_FLOAT, (GLfloat*)col);
|
||||
prevSizeCol = sizeColor;
|
||||
} else {
|
||||
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, sizeColor, GL_RGBA, GL_FLOAT, (GLfloat*)col);
|
||||
}
|
||||
} else {
|
||||
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, sizeColor, GL_RGBA, GL_FLOAT, (GLfloat*)col);
|
||||
// Position
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_2D, data_tex[0]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
if (prevSize < size) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, size, 1, 0, GL_RGB, GL_FLOAT, (GLfloat*)pos);
|
||||
prevSize = size;
|
||||
} else {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, 1, GL_RGB, GL_FLOAT, (GLfloat*)pos);
|
||||
}
|
||||
|
||||
// Texcoords
|
||||
if (hasTexCoords) {
|
||||
glActiveTexture(GL_TEXTURE4);
|
||||
glBindTexture(GL_TEXTURE_2D, data_tex[1]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
if (prevSizeTex < size) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, size, 1, 0, GL_RGB, GL_FLOAT, (GLfloat*)tex);
|
||||
prevSizeTex = size;
|
||||
} else {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, 1, GL_RGB, GL_FLOAT, (GLfloat*)tex);
|
||||
}
|
||||
}
|
||||
|
||||
// Color
|
||||
glActiveTexture(GL_TEXTURE5);
|
||||
glBindTexture(GL_TEXTURE_2D, data_tex[2]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
int sizeColor = hasColor ? size : 1;
|
||||
if (prevSizeCol < sizeColor) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, sizeColor, 1, 0, GL_RGBA, GL_FLOAT, (GLfloat*)col);
|
||||
prevSizeCol = sizeColor;
|
||||
} else {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, sizeColor, 1, GL_RGBA, GL_FLOAT, (GLfloat*)col);
|
||||
}
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
|
|
@ -247,8 +247,9 @@ private:
|
|||
class TessellationDataTransferGLES : public TessellationDataTransfer {
|
||||
private:
|
||||
int data_tex[3];
|
||||
bool isAllowTexture1D;
|
||||
public:
|
||||
TessellationDataTransferGLES() : TessellationDataTransfer(), data_tex() {
|
||||
TessellationDataTransferGLES(bool isAllowTexture1D) : TessellationDataTransfer(), data_tex(), isAllowTexture1D(isAllowTexture1D) {
|
||||
glGenTextures(3, (GLuint*)data_tex);
|
||||
}
|
||||
~TessellationDataTransferGLES() {
|
||||
|
|
|
@ -105,6 +105,8 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
|
|||
const char *varying = "varying";
|
||||
const char *attribute = "attribute";
|
||||
const char * const * boneWeightDecl = boneWeightAttrDecl;
|
||||
const char *texelFetch = NULL;
|
||||
bool isAllowTexture1D = false;
|
||||
bool highpFog = false;
|
||||
bool highpTexcoord = false;
|
||||
|
||||
|
@ -112,8 +114,13 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
|
|||
if (gstate_c.featureFlags & GPU_SUPPORTS_GLSL_ES_300) {
|
||||
WRITE(p, "#version 300 es\n");
|
||||
glslES30 = true;
|
||||
texelFetch = "texelFetch";
|
||||
} else {
|
||||
WRITE(p, "#version 100\n"); // GLSL ES 1.0
|
||||
if (gl_extensions.EXT_gpu_shader4) {
|
||||
WRITE(p, "#extension GL_EXT_gpu_shader4 : enable\n");
|
||||
texelFetch = "texelFetch2D";
|
||||
}
|
||||
}
|
||||
WRITE(p, "precision highp float;\n");
|
||||
|
||||
|
@ -126,10 +133,21 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
|
|||
if (gl_extensions.VersionGEThan(3, 3, 0)) {
|
||||
glslES30 = true;
|
||||
WRITE(p, "#version 330\n");
|
||||
texelFetch = "texelFetch";
|
||||
isAllowTexture1D = true;
|
||||
} else if (gl_extensions.VersionGEThan(3, 0, 0)) {
|
||||
WRITE(p, "#version 130\n");
|
||||
if (gl_extensions.EXT_gpu_shader4) {
|
||||
WRITE(p, "#extension GL_EXT_gpu_shader4 : enable\n");
|
||||
texelFetch = "texelFetch";
|
||||
isAllowTexture1D = true;
|
||||
}
|
||||
} else {
|
||||
WRITE(p, "#version 110\n");
|
||||
if (gl_extensions.EXT_gpu_shader4) {
|
||||
WRITE(p, "#extension GL_EXT_gpu_shader4 : enable\n");
|
||||
texelFetch = "texelFetch2D";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,7 +345,7 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
|
|||
|
||||
// Hardware tessellation
|
||||
if (doBezier || doSpline) {
|
||||
const char *sampler = gl_extensions.IsGLES ? "sampler2D" : "sampler1D";
|
||||
const char *sampler = !isAllowTexture1D ? "sampler2D" : "sampler1D";
|
||||
WRITE(p, "uniform %s u_tess_pos_tex;\n", sampler);
|
||||
WRITE(p, "uniform %s u_tess_tex_tex;\n", sampler);
|
||||
WRITE(p, "uniform %s u_tess_col_tex;\n", sampler);
|
||||
|
@ -355,31 +373,31 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
|
|||
|
||||
WRITE(p, "void spline_knot(ivec2 num_patches, ivec2 type, out vec2 knot[6], ivec2 patch_pos) {\n");
|
||||
WRITE(p, " for (int i = 0; i < 6; ++i) {\n");
|
||||
WRITE(p, " knot[i] = vec2(i + patch_pos.x - 2, i + patch_pos.y - 2);\n");
|
||||
WRITE(p, " knot[i] = vec2(float(i + patch_pos.x - 2), float(i + patch_pos.y - 2));\n");
|
||||
WRITE(p, " }\n");
|
||||
WRITE(p, " if ((type.x & 1) != 0) {\n");
|
||||
WRITE(p, " if (patch_pos.x <= 2)\n");
|
||||
WRITE(p, " knot[0].x = 0;\n");
|
||||
WRITE(p, " knot[0].x = 0.0;\n");
|
||||
WRITE(p, " if (patch_pos.x <= 1)\n");
|
||||
WRITE(p, " knot[1].x = 0;\n");
|
||||
WRITE(p, " knot[1].x = 0.0;\n");
|
||||
WRITE(p, " }\n");
|
||||
WRITE(p, " if ((type.x & 2) != 0) {\n");
|
||||
WRITE(p, " if (patch_pos.x >= (num_patches.x - 2))\n");
|
||||
WRITE(p, " knot[5].x = num_patches.x;\n");
|
||||
WRITE(p, " knot[5].x = float(num_patches.x);\n");
|
||||
WRITE(p, " if (patch_pos.x == (num_patches.x - 1))\n");
|
||||
WRITE(p, " knot[4].x = num_patches.x;\n");
|
||||
WRITE(p, " knot[4].x = float(num_patches.x);\n");
|
||||
WRITE(p, " }\n");
|
||||
WRITE(p, " if ((type.y & 1) != 0) {\n");
|
||||
WRITE(p, " if (patch_pos.y <= 2)\n");
|
||||
WRITE(p, " knot[0].y = 0;\n");
|
||||
WRITE(p, " knot[0].y = 0.0;\n");
|
||||
WRITE(p, " if (patch_pos.y <= 1)\n");
|
||||
WRITE(p, " knot[1].y = 0;\n");
|
||||
WRITE(p, " knot[1].y = 0.0;\n");
|
||||
WRITE(p, " }\n");
|
||||
WRITE(p, " if ((type.y & 2) != 0) {\n");
|
||||
WRITE(p, " if (patch_pos.y >= (num_patches.y - 2))\n");
|
||||
WRITE(p, " knot[5].y = num_patches.y;\n");
|
||||
WRITE(p, " knot[5].y = float(num_patches.y);\n");
|
||||
WRITE(p, " if (patch_pos.y == (num_patches.y - 1))\n");
|
||||
WRITE(p, " knot[4].y = num_patches.y;\n");
|
||||
WRITE(p, " knot[4].y = float(num_patches.y);\n");
|
||||
WRITE(p, " }\n");
|
||||
WRITE(p, "}\n");
|
||||
|
||||
|
@ -449,18 +467,18 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
|
|||
WRITE(p, " vec2 _tex[16];\n");
|
||||
WRITE(p, " vec4 _col[16];\n");
|
||||
WRITE(p, " int num_patches_u = %s;\n", doBezier ? "(u_spline_count_u - 1) / 3" : "u_spline_count_u - 3");
|
||||
WRITE(p, " int u = int(mod(gl_InstanceID, num_patches_u));\n");
|
||||
WRITE(p, " int v = (gl_InstanceID / num_patches_u);\n");
|
||||
WRITE(p, " int u = int(mod(float(gl_InstanceID), float(num_patches_u)));\n");
|
||||
WRITE(p, " int v = gl_InstanceID / num_patches_u;\n");
|
||||
WRITE(p, " ivec2 patch_pos = ivec2(u, v);\n");
|
||||
WRITE(p, " for (int i = 0; i < 4; i++) {\n");
|
||||
WRITE(p, " for (int j = 0; j < 4; j++) {\n");
|
||||
WRITE(p, " int index = (i + v%s) * u_spline_count_u + (j + u%s);\n", doBezier ? " * 3" : "", doBezier ? " * 3" : "");
|
||||
const char *index = gl_extensions.IsGLES ? "ivec2(index, 0)" : "index";
|
||||
WRITE(p, " _pos[i * 4 + j] = texelFetch(u_tess_pos_tex, %s, 0).xyz;\n", index);
|
||||
const char *index = !isAllowTexture1D ? "ivec2(index, 0)" : "index";
|
||||
WRITE(p, " _pos[i * 4 + j] = %s(u_tess_pos_tex, %s, 0).xyz;\n", texelFetch, index);
|
||||
if (doTexture && hasTexcoord && hasTexcoordTess)
|
||||
WRITE(p, " _tex[i * 4 + j] = texelFetch(u_tess_tex_tex, %s, 0).xy;\n", index);
|
||||
WRITE(p, " _tex[i * 4 + j] = %s(u_tess_tex_tex, %s, 0).xy;\n", texelFetch, index);
|
||||
if (hasColor && hasColorTess)
|
||||
WRITE(p, " _col[i * 4 + j] = texelFetch(u_tess_col_tex, %s, 0).rgba;\n", index);
|
||||
WRITE(p, " _col[i * 4 + j] = %s(u_tess_col_tex, %s, 0).rgba;\n", texelFetch, index);
|
||||
WRITE(p, " }\n");
|
||||
WRITE(p, " }\n");
|
||||
WRITE(p, " vec2 tess_pos = position.xy;\n");
|
||||
|
@ -476,20 +494,20 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
|
|||
WRITE(p, " ivec2 spline_type = ivec2(u_spline_type_u, u_spline_type_v);\n");
|
||||
WRITE(p, " vec2 knots[6];\n");
|
||||
WRITE(p, " spline_knot(spline_num_patches, spline_type, knots, patch_pos);\n");
|
||||
WRITE(p, " spline_weight(tess_pos + patch_pos, knots, weights);\n");
|
||||
WRITE(p, " spline_weight(tess_pos + vec2(patch_pos), knots, weights);\n");
|
||||
}
|
||||
WRITE(p, " vec3 pos = tess_sample(_pos, weights);\n");
|
||||
if (doTexture && hasTexcoord) {
|
||||
if (hasTexcoordTess)
|
||||
WRITE(p, " vec2 tex = tess_sample(_tex, weights);\n");
|
||||
else
|
||||
WRITE(p, " vec2 tex = tess_pos + patch_pos;\n");
|
||||
WRITE(p, " vec2 tex = tess_pos + vec2(patch_pos);\n");
|
||||
}
|
||||
if (hasColor) {
|
||||
if (hasColorTess)
|
||||
WRITE(p, " vec4 col = tess_sample(_col, weights);\n");
|
||||
else
|
||||
WRITE(p, " vec4 col = texelFetch(u_tess_col_tex, %s, 0).rgba;\n", gl_extensions.IsGLES ? "ivec2(0, 0)" : "0");
|
||||
WRITE(p, " vec4 col = %s(u_tess_col_tex, %s, 0).rgba;\n", texelFetch, !isAllowTexture1D ? "ivec2(0, 0)" : "0");
|
||||
}
|
||||
if (hasNormal) {
|
||||
// Curved surface is probably always need to compute normal(not sampling from control points)
|
||||
|
@ -515,19 +533,19 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
|
|||
WRITE(p, " vec2 tess_next_v = vec2(0.0, normal.y);\n");
|
||||
// Right
|
||||
WRITE(p, " vec2 tess_pos_r = tess_pos + tess_next_u;\n");
|
||||
WRITE(p, " spline_weight(tess_pos_r + patch_pos, knots, weights);\n");
|
||||
WRITE(p, " spline_weight(tess_pos_r + vec2(patch_pos), knots, weights);\n");
|
||||
WRITE(p, " vec3 pos_r = tess_sample(_pos, weights);\n");
|
||||
// Left
|
||||
WRITE(p, " vec2 tess_pos_l = tess_pos - tess_next_u;\n");
|
||||
WRITE(p, " spline_weight(tess_pos_l + patch_pos, knots, weights);\n");
|
||||
WRITE(p, " spline_weight(tess_pos_l + vec2(patch_pos), knots, weights);\n");
|
||||
WRITE(p, " vec3 pos_l = tess_sample(_pos, weights);\n");
|
||||
// Down
|
||||
WRITE(p, " vec2 tess_pos_d = tess_pos + tess_next_v;\n");
|
||||
WRITE(p, " spline_weight(tess_pos_d + patch_pos, knots, weights);\n");
|
||||
WRITE(p, " spline_weight(tess_pos_d + vec2(patch_pos), knots, weights);\n");
|
||||
WRITE(p, " vec3 pos_d = tess_sample(_pos, weights);\n");
|
||||
// Up
|
||||
WRITE(p, " vec2 tess_pos_u = tess_pos - tess_next_v;\n");
|
||||
WRITE(p, " spline_weight(tess_pos_u + patch_pos, knots, weights);\n");
|
||||
WRITE(p, " spline_weight(tess_pos_u + vec2(patch_pos), knots, weights);\n");
|
||||
WRITE(p, " vec3 pos_u = tess_sample(_pos, weights);\n");
|
||||
|
||||
WRITE(p, " vec3 du = pos_r - pos_l;\n");
|
||||
|
|
Loading…
Add table
Reference in a new issue