Rain: Precompute as many shader data as possible
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14812 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
9826af0747
commit
616a2e7a75
@ -181,20 +181,41 @@ GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_pat
|
|||||||
return ProgramID;
|
return ProgramID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount){
|
||||||
|
GLuint Shader = LoadShader(vertex_file_path, GL_VERTEX_SHADER);
|
||||||
|
GLuint Program = glCreateProgram();
|
||||||
|
glAttachShader(Program, Shader);
|
||||||
|
glTransformFeedbackVaryings(Program, varyingscount, varyings, GL_INTERLEAVED_ATTRIBS);
|
||||||
|
glLinkProgram(Program);
|
||||||
|
|
||||||
|
GLint Result = GL_FALSE;
|
||||||
|
int InfoLogLength;
|
||||||
|
glGetProgramiv(Program, GL_LINK_STATUS, &Result);
|
||||||
|
if (Result == GL_FALSE) {
|
||||||
|
glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
||||||
|
char *ErrorMessage = new char[InfoLogLength];
|
||||||
|
glGetProgramInfoLog(Program, InfoLogLength, NULL, ErrorMessage);
|
||||||
|
printf(ErrorMessage);
|
||||||
|
delete[] ErrorMessage;
|
||||||
|
}
|
||||||
|
glDeleteShader(Shader);
|
||||||
|
return Program;
|
||||||
|
}
|
||||||
|
|
||||||
GLuint getTextureGLuint(ITexture *tex) { return static_cast<const COpenGLTexture*>(tex)->getOpenGLTextureName(); }
|
GLuint getTextureGLuint(ITexture *tex) { return static_cast<const COpenGLTexture*>(tex)->getOpenGLTextureName(); }
|
||||||
|
|
||||||
void bindUniformToTextureUnit(GLuint program, const char * name, GLuint texid, unsigned textureUnit) {
|
void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit) {
|
||||||
glActiveTexture(GL_TEXTURE0 + textureUnit);
|
glActiveTexture(GL_TEXTURE0 + textureUnit);
|
||||||
glBindTexture(GL_TEXTURE_2D, texid);
|
glBindTexture(GL_TEXTURE_2D, texid);
|
||||||
GLuint location = glGetUniformLocation(program, name);
|
|
||||||
glUniform1i(location, textureUnit);
|
glUniform1i(location, textureUnit);
|
||||||
}
|
}
|
||||||
|
|
||||||
class GPUParticle {
|
class GPUParticle {
|
||||||
private:
|
private:
|
||||||
GLuint SimulationProgram, RenderProgram, tfb_vertex_buffer[2];
|
GLuint SimulationProgram, RenderProgram, tfb_vertex_buffer[2];
|
||||||
GLuint texture;
|
GLuint texture, normal_and_depth;
|
||||||
GLuint normal_and_depth;
|
GLuint loc_campos, loc_viewm, loc_time;
|
||||||
|
GLuint loc_screenw, loc_screen, loc_invproj, texloc_tex, texloc_normal_and_depths;
|
||||||
unsigned count;
|
unsigned count;
|
||||||
public:
|
public:
|
||||||
GPUParticle(unsigned c, float *initialSamples, GLuint tex, GLuint rtt) :
|
GPUParticle(unsigned c, float *initialSamples, GLuint tex, GLuint rtt) :
|
||||||
@ -207,24 +228,17 @@ public:
|
|||||||
glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), 0, GL_STREAM_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), 0, GL_STREAM_DRAW);
|
||||||
|
|
||||||
RenderProgram = LoadProgram(file_manager->getAsset("shaders/rain.vert").c_str(), file_manager->getAsset("shaders/rain.frag").c_str());
|
RenderProgram = LoadProgram(file_manager->getAsset("shaders/rain.vert").c_str(), file_manager->getAsset("shaders/rain.frag").c_str());
|
||||||
GLuint SimShader = LoadShader(file_manager->getAsset("shaders/rainsim.vert").c_str(), GL_VERTEX_SHADER);
|
loc_screenw = glGetUniformLocation(RenderProgram, "screenw");
|
||||||
SimulationProgram = glCreateProgram();
|
loc_screen = glGetUniformLocation(RenderProgram, "screen");
|
||||||
glAttachShader(SimulationProgram, SimShader);
|
loc_invproj = glGetUniformLocation(RenderProgram, "invproj");
|
||||||
const char *varying[] = { "currentPosition" };
|
texloc_tex = glGetUniformLocation(RenderProgram, "tex");
|
||||||
glTransformFeedbackVaryings(SimulationProgram, 1, varying, GL_INTERLEAVED_ATTRIBS);
|
texloc_normal_and_depths = glGetUniformLocation(RenderProgram, "normals_and_depth");
|
||||||
glLinkProgram(SimulationProgram);
|
|
||||||
|
|
||||||
GLint Result = GL_FALSE;
|
const char *varyings[] = {"currentPosition"};
|
||||||
int InfoLogLength;
|
SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/rainsim.vert").c_str(), varyings, 1);
|
||||||
glGetProgramiv(SimulationProgram, GL_LINK_STATUS, &Result);
|
loc_campos = glGetUniformLocation(SimulationProgram, "campos");
|
||||||
if (Result == GL_FALSE) {
|
loc_viewm = glGetUniformLocation(SimulationProgram, "viewm");
|
||||||
glGetProgramiv(SimulationProgram, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
loc_time = glGetUniformLocation(SimulationProgram, "time");
|
||||||
char *ErrorMessage = new char[InfoLogLength];
|
|
||||||
glGetProgramInfoLog(SimulationProgram, InfoLogLength, NULL, ErrorMessage);
|
|
||||||
printf(ErrorMessage);
|
|
||||||
delete[] ErrorMessage;
|
|
||||||
}
|
|
||||||
glDeleteShader(SimShader);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void simulate() {
|
void simulate() {
|
||||||
@ -238,12 +252,10 @@ public:
|
|||||||
glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]);
|
glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]);
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
||||||
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_vertex_buffer[1]);
|
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_vertex_buffer[1]);
|
||||||
GLuint lcampos = glGetUniformLocation(SimulationProgram, "campos");
|
|
||||||
GLuint lviewm = glGetUniformLocation(SimulationProgram, "viewm");
|
glUniformMatrix4fv(loc_viewm, 1, GL_FALSE, viewm.pointer());
|
||||||
GLuint ltime = glGetUniformLocation(SimulationProgram, "time");
|
glUniform1f(loc_time, time);
|
||||||
glUniformMatrix4fv(lviewm, 1, GL_FALSE, viewm.pointer());
|
glUniform3f(loc_campos, campos.X, campos.Y, campos.Z);
|
||||||
glUniform1f(ltime, time);
|
|
||||||
glUniform3f(lcampos, campos.X, campos.Y, campos.Z);
|
|
||||||
glBeginTransformFeedback(GL_POINTS);
|
glBeginTransformFeedback(GL_POINTS);
|
||||||
glDrawArrays(GL_POINTS, 0, count);
|
glDrawArrays(GL_POINTS, 0, count);
|
||||||
glEndTransformFeedback();
|
glEndTransformFeedback();
|
||||||
@ -265,19 +277,12 @@ public:
|
|||||||
matrix4 invproj = irr_driver->getVideoDriver()->getTransform(ETS_PROJECTION);
|
matrix4 invproj = irr_driver->getVideoDriver()->getTransform(ETS_PROJECTION);
|
||||||
invproj.makeInverse();
|
invproj.makeInverse();
|
||||||
|
|
||||||
GLuint lscreenw = glGetUniformLocation(RenderProgram, "screenw");
|
bindUniformToTextureUnit(texloc_tex, texture, 0);
|
||||||
GLuint bdiscard = glGetUniformLocation(RenderProgram, "bdiscard");
|
bindUniformToTextureUnit(texloc_normal_and_depths, normal_and_depth, 1);
|
||||||
GLuint lscreen = glGetUniformLocation(RenderProgram, "screen");
|
|
||||||
GLuint linvproj = glGetUniformLocation(RenderProgram, "invproj");
|
|
||||||
|
|
||||||
bindUniformToTextureUnit(RenderProgram, "tex", texture, 0);
|
glUniformMatrix4fv(loc_invproj, 1, GL_FALSE, invproj.pointer());
|
||||||
bindUniformToTextureUnit(RenderProgram, "normals_and_depth", normal_and_depth, 1);
|
glUniform2f(loc_screen, screen[0], screen[1]);
|
||||||
|
glUniform1f(loc_screenw, screenw);
|
||||||
|
|
||||||
glUniformMatrix4fv(linvproj, 1, GL_FALSE, invproj.pointer());
|
|
||||||
glUniform2f(lscreen, screen[0], screen[1]);
|
|
||||||
glUniform1f(bdiscard, 1.0);
|
|
||||||
glUniform1f(lscreenw, screenw);
|
|
||||||
glDrawArrays(GL_POINTS, 0, count);
|
glDrawArrays(GL_POINTS, 0, count);
|
||||||
glDisableVertexAttribArray(0);
|
glDisableVertexAttribArray(0);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user