Как рябить на сфере

Я пытаюсь реализовать программу, которая превращает куб в сферу, основанную на нажатиях клавиш, и колеблется при каждом нажатии. Мне удалось реализовать часть куба в сферу и обратно, но я совершенно не представляю, с чего начать рябь. Я просмотрел множество источников в Интернете, у меня есть математика, но я понятия не имею, как реализовать ее в моем вершинном шейдере. Может ли кто-нибудь помочь мне с моей дилеммой? Спасибо!

Вот мои cpp, vsh и fsh: https://drive.google.com/file/d/0B4hkcF9foOTgbUozMjZmSHJhQWM/view?usp=sharing

Я использую GLSL, OpenGL 4.4.0

Вот мой код для вершинного шейдера:

    #version 120

attribute vec3 pos;
varying vec4 out_color;
uniform float t;
float PI = 3.14159265357;

int factor = 2; //for determining colors
int num_colors; // = factor * 3 (because RGB)
float currang = 0;
float angfac;

vec4 calculate( float a )
{
//this is just to calculate for the color
}

void main() {
num_colors = factor*3;
angfac = 2*PI/num_colors;

float ang = atan( pos.z, pos.x )+PI;
out_color = calculate(ang);

//rotation
mat3 rotateX = mat3(
vec3( 1,         0,        0),
vec3( 0,    cos(t),   sin(t)),
vec3( 0,   -sin(t),   cos(t))
);

mat3 rotateY = mat3(
vec3( cos(t),    0,   -sin(t)),
vec3( 0,         1,         0),
vec3( sin(t),    0,    cos(t))
);

mat3 rotateZ = mat3(
vec3( cos(t),    sin(t),       0),
vec3(-sin(t),    cos(t),       0),
vec3(      0,         0,  cos(t))
);

gl_Position = gl_ModelViewProjectionMatrix * vec4((pos.xyz*rotateY*rotateX) , 1.0 );
}

и вот части моего файла cpp:

//usual include statements

using namespace std;

enum { ATTRIB_POS };
GLuint mainProgram = 0;

// I use this to indicate the position of the vertices
struct Vtx {
GLfloat x, y, z;
};

const GLfloat PI = 3.14159265357;

const int sideLength = 10;
const size_t nVertices = (sideLength*sideLength*sideLength)-((sideLength-2)*(sideLength-2)*(sideLength-2));

Vtx cube[nVertices];
Vtx sphere[nVertices];
Vtx diff[nVertices];

const double TIME_SPEED = 0.01;

int mI = 4*(sideLength-1);
const int sLCubed = sideLength*sideLength*sideLength;
int indices[nVertices*nVertices];

GLfloat originX = 0.0f; //offset
GLfloat originY = 0.0f; //offset

bool loadShaderSource(GLuint shader, const char *path) {...}

void checkShaderStatus(GLuint shader) {...}

bool initShader() {...}

//in this part of the code, I instantiate an array of indices to be used by glDrawElements()

void transform(int fac)
{
//move from cube to sphere and back by adding/subtracting values and updating cube[].xyz
//moveSpeed = diff[]/speedFac
//fac is to determine direction (going to sphere or going to cube; going to sphere is plus, going back to cube is minus)
for( int i = 0; i<nVertices; i++ )
{
cube[i].x += fac*diff[i].x;
cube[i].y += fac*diff[i].y;
cube[i].z += fac*diff[i].z;
}
}

void initCube() {...} //computation for the vertices of the cube depending on sideLength

void initSphere() {...} //computation for the vertices of the sphere based on the vertices of the cube

void toSphere() {...} //changes the values of the array of vertices of the cube to those of the sphere

void initDiff() {...} //computes for the difference of the values of the vertices of the sphere and the vertices of the cube for the slow transformation

int main() {
//error checking (GLEW, OpenGL versions, etc)

glfwSetWindowTitle("CS177 Final Project");
glfwEnable( GLFW_STICKY_KEYS );
glfwSwapInterval( 1 );
glClearColor(0,0,0,0);
if ( !initShader() ) {
return -1;
}

glEnableVertexAttribArray(ATTRIB_POS);
glVertexAttribPointer(ATTRIB_POS, 3, GL_FLOAT, GL_FALSE, sizeof(Vtx), cube);

initCube();
initIndices();
initSphere();
initDiff();

glUseProgram(mainProgram);
GLuint UNIF_T = glGetUniformLocation(mainProgram, "t");

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
float t = 0;
glUniform1f(UNIF_T, t);

glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);

glPointSize(2.0);
glEnable(GL_POINT_SMOOTH);

glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);

glfwOpenWindowHint(GLFW_FSAA_SAMPLES,16);
glEnable(GL_MULTISAMPLE);

do {
int width, height;
glfwGetWindowSize( &width, &height );
glViewport( 0, 0, width, height );

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
t += TIME_SPEED;
glUniform1f(UNIF_T, t);

if (glfwGetKey(GLFW_KEY_DEL)) transform(-1);
if (glfwGetKey(GLFW_KEY_INSERT)) transform( 1 );
if (glfwGetKey(GLFW_KEY_HOME)) initCube();
if (glfwGetKey(GLFW_KEY_END)) toSphere();

glDrawElements( GL_TRIANGLES, nVertices*nVertices, GL_UNSIGNED_INT, indices);

glfwSwapBuffers();
} while ( glfwGetKey(GLFW_KEY_ESC) != GLFW_PRESS &&
glfwGetWindowParam(GLFW_OPENED) );

glDeleteProgram(mainProgram);
glfwTerminate();
return 0;
}

1

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы [email protected]