| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #include "../shaders.h" |
| |
|
| | #include "../../core/mesh.h" |
| | #include "../../core/tga.h" |
| | #include "../../core/platform.h" |
| | #include "../../core/extrude.h" |
| |
|
| | #include "../../external/SDL2-2.0.4/include/SDL.h" |
| | #include "../../external/glad/src/glad.c" |
| |
|
| | |
| | #include "../../external/glad/src/glad_egl.c" |
| | #include "../../external/glad/include/glad/glad_egl.h" |
| | |
| |
|
| | #include "imguiRenderGL.h" |
| | #include "utilsGL.h" |
| |
|
| | #include "shader.h" |
| |
|
| | #ifdef ANDROID |
| | #include "android/Log.h" |
| | #include "android/AndroidDefine.h" |
| | #include "android/AndroidMatrixTool.h" |
| | #endif |
| |
|
| |
|
| | #define CudaCheck(x) { cudaError_t err = x; if (err != cudaSuccess) { printf("Cuda error: %d in %s at %s:%d\n", err, #x, __FILE__, __LINE__); assert(0); } } |
| |
|
| | typedef unsigned int VertexBuffer; |
| | typedef unsigned int IndexBuffer; |
| | typedef unsigned int Texture; |
| |
|
| | struct FluidRenderBuffersGL |
| | { |
| | FluidRenderBuffersGL(int numParticles = 0): |
| | mPositionVBO(0), |
| | mDensityVBO(0), |
| | mIndices(0), |
| | mPositionBuf(nullptr), |
| | mDensitiesBuf(nullptr), |
| | mIndicesBuf(nullptr) |
| | { |
| | mNumParticles = numParticles; |
| | for (int i = 0; i < 3; i++) |
| | { |
| | mAnisotropyVBO[i] = 0; |
| | mAnisotropyBuf[i] = nullptr; |
| | } |
| | } |
| | ~FluidRenderBuffersGL() |
| | { |
| | glDeleteBuffers(1, &mPositionVBO); |
| | glDeleteBuffers(3, mAnisotropyVBO); |
| | glDeleteBuffers(1, &mDensityVBO); |
| | glDeleteBuffers(1, &mIndices); |
| |
|
| | NvFlexUnregisterOGLBuffer(mPositionBuf); |
| | NvFlexUnregisterOGLBuffer(mDensitiesBuf); |
| | NvFlexUnregisterOGLBuffer(mIndicesBuf); |
| |
|
| | NvFlexUnregisterOGLBuffer(mAnisotropyBuf[0]); |
| | NvFlexUnregisterOGLBuffer(mAnisotropyBuf[1]); |
| | NvFlexUnregisterOGLBuffer(mAnisotropyBuf[2]); |
| | } |
| |
|
| | int mNumParticles; |
| | VertexBuffer mPositionVBO; |
| | VertexBuffer mDensityVBO; |
| | VertexBuffer mAnisotropyVBO[3]; |
| | IndexBuffer mIndices; |
| |
|
| | |
| | NvFlexBuffer* mPositionBuf; |
| | NvFlexBuffer* mDensitiesBuf; |
| | NvFlexBuffer* mAnisotropyBuf[3]; |
| | NvFlexBuffer* mIndicesBuf; |
| | }; |
| |
|
| | |
| | struct DiffuseRenderBuffersGL |
| | { |
| | DiffuseRenderBuffersGL(int numParticles = 0): |
| | mDiffusePositionVBO(0), |
| | mDiffuseVelocityVBO(0), |
| | mDiffuseIndicesIBO(0), |
| | mDiffuseIndicesBuf(nullptr), |
| | mDiffusePositionsBuf(nullptr), |
| | mDiffuseVelocitiesBuf(nullptr) |
| | { |
| | mNumParticles = numParticles; |
| | } |
| | ~DiffuseRenderBuffersGL() |
| | { |
| | if (mNumParticles > 0) |
| | { |
| | glDeleteBuffers(1, &mDiffusePositionVBO); |
| | glDeleteBuffers(1, &mDiffuseVelocityVBO); |
| | glDeleteBuffers(1, &mDiffuseIndicesIBO); |
| |
|
| | NvFlexUnregisterOGLBuffer(mDiffuseIndicesBuf); |
| | NvFlexUnregisterOGLBuffer(mDiffusePositionsBuf); |
| | NvFlexUnregisterOGLBuffer(mDiffuseVelocitiesBuf); |
| | } |
| | } |
| |
|
| | int mNumParticles; |
| | VertexBuffer mDiffusePositionVBO; |
| | VertexBuffer mDiffuseVelocityVBO; |
| | IndexBuffer mDiffuseIndicesIBO; |
| |
|
| | NvFlexBuffer* mDiffuseIndicesBuf; |
| | NvFlexBuffer* mDiffusePositionsBuf; |
| | NvFlexBuffer* mDiffuseVelocitiesBuf; |
| | }; |
| |
|
| | struct FluidRenderer |
| | { |
| | GLuint mDepthFbo; |
| | GLuint mDepthTex; |
| | GLuint mDepthSmoothTex; |
| | GLuint mSceneFbo; |
| | GLuint mSceneTex; |
| | GLuint mReflectTex; |
| |
|
| | GLuint mThicknessFbo; |
| | GLuint mThicknessTex; |
| |
|
| | GLuint mPointThicknessProgram; |
| | |
| |
|
| | GLuint mEllipsoidThicknessProgram; |
| | GLuint mEllipsoidDepthProgram; |
| |
|
| | GLuint mCompositeProgram; |
| | GLuint mDepthBlurProgram; |
| |
|
| | int mSceneWidth; |
| | int mSceneHeight; |
| | }; |
| |
|
| | struct ShadowMap |
| | { |
| | GLuint texture; |
| | GLuint framebuffer; |
| | }; |
| |
|
| | struct GpuMesh |
| | { |
| | GLuint mPositionsVBO; |
| | GLuint mNormalsVBO; |
| | GLuint mIndicesIBO; |
| |
|
| | int mNumVertices; |
| | int mNumFaces; |
| | }; |
| |
|
| | |
| | #include "../../core/png.h" |
| |
|
| | GLuint LoadTexture(const char* filename) |
| | { |
| | PngImage img; |
| | if (PngLoad(filename, img)) |
| | { |
| | GLuint tex; |
| |
|
| | glVerify(glGenTextures(1, &tex)); |
| | glVerify(glActiveTexture(GL_TEXTURE0)); |
| | glVerify(glBindTexture(GL_TEXTURE_2D, tex)); |
| |
|
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE)); |
| | glVerify(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.m_width, img.m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.m_data)); |
| |
|
| | PngFree(img); |
| |
|
| | return tex; |
| | } |
| | else |
| | { |
| | return NULL; |
| | } |
| | } |
| |
|
| | struct RenderTexture |
| | { |
| | GLuint colorTex; |
| | GLuint colorFrameBuffer; |
| |
|
| | GLuint depthTex; |
| | GLuint depthFrameBuffer; |
| |
|
| | RenderTexture() |
| | { |
| | memset(this, 0, sizeof(*this)); |
| | } |
| | }; |
| |
|
| | namespace |
| | { |
| |
|
| | int g_msaaSamples; |
| | GLuint g_msaaFbo; |
| | GLuint g_msaaColorBuf; |
| | GLuint g_msaaDepthBuf; |
| |
|
| | int g_screenWidth; |
| | int g_screenHeight; |
| |
|
| | SDL_Window* g_window; |
| |
|
| | static float g_spotMin = 0.5f; |
| | static float g_spotMax = 1.0f; |
| | float g_shadowBias = 0.05f; |
| |
|
| | #ifdef __linux__ |
| | EGLDisplay* g_eglDisplay; |
| | EGLConfig* g_eglConfig; |
| | EGLContext* g_eglContext; |
| | EGLSurface* g_eglSurface; |
| | #endif |
| |
|
| | } |
| |
|
| | extern NvFlexLibrary* g_flexLib; |
| | extern Colour g_colors[]; |
| |
|
| | extern Mesh* g_mesh; |
| | void DrawShapes(); |
| |
|
| | namespace OGL_Renderer |
| | { |
| |
|
| | char font_path[100]; |
| |
|
| | char* make_path(char* full_path, std::string path) { |
| | strcpy(full_path, getenv("PYFLEXROOT")); |
| | strcat(full_path, path.c_str()); |
| | return full_path; |
| | } |
| |
|
| | void InitRender(const RenderInitOptions& options) |
| | { |
| | SDL_Window* window = options.window; |
| | int msaaSamples = options.numMsaaSamples; |
| |
|
| | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); |
| | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); |
| |
|
| | |
| | SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); |
| |
|
| | |
| | SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); |
| | SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); |
| |
|
| | SDL_GL_CreateContext(window); |
| |
|
| | |
| | SDL_GL_SetSwapInterval(1); |
| |
|
| | if (!gladLoadGLLoader(SDL_GL_GetProcAddress)) |
| | { |
| | printf("Could not initialize GL extensions\n"); |
| | } |
| |
|
| | imguiRenderGLInit(GetFilePathByPlatform(make_path(font_path, "/data/DroidSans.ttf")).c_str()); |
| |
|
| | g_msaaSamples = msaaSamples; |
| | g_window = window; |
| | } |
| |
|
| | void DestroyRender() |
| | { |
| | } |
| |
|
| | void StartFrame(Vec4 clearColor) |
| | { |
| | glEnable(GL_DEPTH_TEST); |
| | glEnable(GL_CULL_FACE); |
| | glDisable(GL_LIGHTING); |
| | glDisable(GL_BLEND); |
| |
|
| | glPointSize(5.0f); |
| |
|
| | glVerify(glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, g_msaaFbo)); |
| | glVerify(glClearColor(powf(clearColor.x, 1.0f / 2.2f), powf(clearColor.y, 1.0f / 2.2f), powf(clearColor.z, 1.0f / 2.2f), 0.0f)); |
| | glVerify(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); |
| |
|
| |
|
| | } |
| |
|
| | void EndFrame() |
| | { |
| | if (g_msaaFbo) |
| | { |
| | |
| | glVerify(glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, g_msaaFbo)); |
| | glVerify(glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, 0)); |
| | glVerify(glBlitFramebuffer(0, 0, g_screenWidth, g_screenHeight, 0, 0, g_screenWidth, g_screenHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR)); |
| | } |
| |
|
| | |
| | glVerify(glBindFramebuffer(GL_FRAMEBUFFER, 0)); |
| | |
| |
|
| | } |
| |
|
| | void SetView(Matrix44 view, Matrix44 proj) |
| | { |
| | glMatrixMode(GL_PROJECTION); |
| | glLoadMatrixf(proj); |
| |
|
| | glMatrixMode(GL_MODELVIEW); |
| | glLoadMatrixf(view); |
| | } |
| |
|
| | void SetFillMode(bool wireframe) |
| | { |
| | glPolygonMode(GL_FRONT_AND_BACK, wireframe?GL_LINE:GL_FILL); |
| | } |
| |
|
| | void SetCullMode(bool enabled) |
| | { |
| | if (enabled) |
| | glEnable(GL_CULL_FACE); |
| | else |
| | glDisable(GL_CULL_FACE); |
| | } |
| |
|
| |
|
| | void imguiGraphDraw() |
| | { |
| | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); |
| |
|
| | glActiveTexture(GL_TEXTURE0); |
| | glDisable(GL_TEXTURE_2D); |
| | glDisable(GL_TEXTURE_RECTANGLE_ARB); |
| | glActiveTexture(GL_TEXTURE1); |
| | glDisable(GL_TEXTURE_2D); |
| | glActiveTexture(GL_TEXTURE2); |
| | glDisable(GL_TEXTURE_2D); |
| | glActiveTexture(GL_TEXTURE3); |
| | glDisable(GL_TEXTURE_2D); |
| | glActiveTexture(GL_TEXTURE4); |
| | glDisable(GL_TEXTURE_2D); |
| | glDisable(GL_TEXTURE_CUBE_MAP); |
| | glActiveTexture(GL_TEXTURE5); |
| | glDisable(GL_TEXTURE_2D); |
| |
|
| | glActiveTexture(GL_TEXTURE0); |
| |
|
| | glDisable(GL_BLEND); |
| | glDisable(GL_LIGHTING); |
| | glDisable(GL_BLEND); |
| | glDisable(GL_POINT_SPRITE); |
| |
|
| | |
| | glMatrixMode(GL_MODELVIEW); |
| | glPushMatrix(); |
| | glLoadIdentity(); |
| |
|
| | const Matrix44 ortho = OrthographicMatrix(0.0f, float(g_screenWidth), 0.0f, float(g_screenHeight), -1.0f, 1.0f); |
| |
|
| | glMatrixMode(GL_PROJECTION); |
| | glPushMatrix(); |
| | glLoadMatrixf(ortho); |
| |
|
| | glUseProgram(0); |
| | glDisable(GL_DEPTH_TEST); |
| | glDisable(GL_CULL_FACE); |
| | glEnable(GL_BLEND); |
| | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
| | glDisable(GL_TEXTURE_2D); |
| | glColor4f(1.0f, 1.0f, 1.0f, 1.0f); |
| |
|
| | imguiRenderGLDraw(); |
| |
|
| | |
| | glMatrixMode(GL_MODELVIEW); |
| | glPopMatrix(); |
| |
|
| | glMatrixMode(GL_PROJECTION); |
| | glPopMatrix(); |
| | } |
| |
|
| | void ReshapeRender(int width, int height, bool minimized) |
| | { |
| | if (g_msaaSamples) |
| | { |
| | glVerify(glBindFramebuffer(GL_FRAMEBUFFER, 0)); |
| |
|
| | if (g_msaaFbo) |
| | { |
| | glVerify(glDeleteFramebuffers(1, &g_msaaFbo)); |
| | glVerify(glDeleteRenderbuffers(1, &g_msaaColorBuf)); |
| | glVerify(glDeleteRenderbuffers(1, &g_msaaDepthBuf)); |
| | } |
| |
|
| | int samples; |
| | glGetIntegerv(GL_MAX_SAMPLES_EXT, &samples); |
| |
|
| | |
| | samples = Min(samples, Min(g_msaaSamples, 4)); |
| |
|
| | glVerify(glGenFramebuffers(1, &g_msaaFbo)); |
| | glVerify(glBindFramebuffer(GL_FRAMEBUFFER, g_msaaFbo)); |
| |
|
| | glVerify(glGenRenderbuffers(1, &g_msaaColorBuf)); |
| | glVerify(glBindRenderbuffer(GL_RENDERBUFFER, g_msaaColorBuf)); |
| | glVerify(glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGBA8, width, height)); |
| |
|
| | glVerify(glGenRenderbuffers(1, &g_msaaDepthBuf)); |
| | glVerify(glBindRenderbuffer(GL_RENDERBUFFER, g_msaaDepthBuf)); |
| | glVerify(glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT, width, height)); |
| | glVerify(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, g_msaaDepthBuf)); |
| |
|
| | glVerify(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, g_msaaColorBuf)); |
| |
|
| | glVerify(glCheckFramebufferStatus(GL_FRAMEBUFFER)); |
| |
|
| | glEnable(GL_MULTISAMPLE); |
| | } |
| |
|
| | g_screenWidth = width; |
| | g_screenHeight = height; |
| | } |
| |
|
| | void GetViewRay(int x, int y, Vec3& origin, Vec3& dir) |
| | { |
| | float modelview[16]; |
| | glGetFloatv(GL_MODELVIEW_MATRIX, modelview); |
| |
|
| | float projection[16]; |
| | glGetFloatv(GL_PROJECTION_MATRIX, projection); |
| |
|
| | int viewport[4]; |
| | glGetIntegerv(GL_VIEWPORT, viewport); |
| |
|
| | float nearPos[3]; |
| | UnProjectf(float(x), float(y), 0.0f, modelview, projection, viewport, nearPos); |
| |
|
| | float farPos[3]; |
| | UnProjectf(float(x), float(y), 1.0f, modelview, projection, viewport, farPos); |
| |
|
| | origin = Vec3(float(nearPos[0]), float(nearPos[1]), float(nearPos[2])); |
| | dir = Normalize(Vec3(float(farPos[0]-nearPos[0]), float(farPos[1]-nearPos[1]), float(farPos[2]-nearPos[2]))); |
| | } |
| |
|
| | Vec3 GetScreenCoord(Vec3& pos) { |
| | float modelview[16]; |
| | glGetFloatv(GL_MODELVIEW_MATRIX, modelview); |
| |
|
| | float projection[16]; |
| | glGetFloatv(GL_PROJECTION_MATRIX, projection); |
| |
|
| | int viewport[4]; |
| | glGetIntegerv(GL_VIEWPORT, viewport); |
| |
|
| | float screen[3]; |
| | Projectf(pos.x, pos.y, pos.z, modelview, projection, viewport, screen); |
| |
|
| | return Vec3((float)screen[0], (float)screen[1], (float)screen[2]); |
| | } |
| |
|
| | void ReadFrame(int* backbuffer, int width, int height) |
| | { |
| | glVerify(glReadBuffer(GL_BACK)); |
| | glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, backbuffer); |
| | } |
| |
|
| | void PresentFrame(bool fullsync) |
| | { |
| | #ifndef ANDROID |
| | SDL_GL_SetSwapInterval(fullsync); |
| | glFinish(); |
| | SDL_GL_SwapWindow(g_window); |
| | #endif |
| | } |
| |
|
| | RenderTexture* CreateRenderTexture(const char* filename) |
| | { |
| | GLuint tex = LoadTexture(filename); |
| |
|
| | if (tex) |
| | { |
| | RenderTexture* t = new RenderTexture(); |
| | t->colorTex = tex; |
| |
|
| | return t; |
| | } |
| | else |
| | { |
| | return NULL; |
| | } |
| | } |
| |
|
| | RenderTexture* CreateRenderTarget(int width, int height, bool depth) |
| | { |
| | return NULL; |
| | } |
| |
|
| | void DestroyRenderTexture(RenderTexture* t) |
| | { |
| | if (t) |
| | { |
| | if (t->colorTex) |
| | glDeleteTextures(1, &t->colorTex); |
| |
|
| | if (t->colorFrameBuffer) |
| | glDeleteFramebuffers(1, &t->colorFrameBuffer); |
| |
|
| | if (t->depthTex) |
| | glDeleteTextures(1, &t->depthTex); |
| |
|
| | if (t->depthFrameBuffer) |
| | glDeleteFramebuffers(1, &t->depthFrameBuffer); |
| |
|
| | delete t; |
| |
|
| |
|
| | } |
| | } |
| |
|
| |
|
| | |
| | #define USE_HDR_DIFFUSE_BLEND 0 |
| |
|
| | |
| | const char *vertexPointShader = "#version 130\n" STRINGIFY( |
| |
|
| | uniform float pointRadius; |
| | uniform float pointScale; |
| |
|
| | uniform mat4 lightTransform; |
| | uniform vec3 lightDir; |
| | uniform vec3 lightDirView; |
| |
|
| | uniform vec4 colors[8]; |
| |
|
| | uniform vec4 transmission; |
| | uniform int mode; |
| |
|
| | |
| | in float density; |
| | in int phase; |
| | in vec4 velocity; |
| |
|
| | void main() |
| | { |
| | |
| | vec4 viewPos = gl_ModelViewMatrix*vec4(gl_Vertex.xyz, 1.0); |
| |
|
| | gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz, 1.0); |
| | gl_PointSize = -pointScale * (pointRadius / viewPos.z); |
| |
|
| | gl_TexCoord[0] = gl_MultiTexCoord0; |
| | gl_TexCoord[1] = lightTransform*vec4(gl_Vertex.xyz-lightDir*pointRadius*2.0, 1.0); |
| | gl_TexCoord[2] = gl_ModelViewMatrix*vec4(lightDir, 0.0); |
| |
|
| | if (mode == 1) |
| | { |
| | |
| | if (density < 0.0f) |
| | gl_TexCoord[3].xyz = mix(vec3(0.1, 0.1, 1.0), vec3(0.1, 1.0, 1.0), -density); |
| | else |
| | gl_TexCoord[3].xyz = mix(vec3(1.0, 1.0, 1.0), vec3(0.1, 0.2, 1.0), density); |
| | } |
| | else if (mode == 2) |
| | { |
| | gl_PointSize *= clamp(gl_Vertex.w*0.25, 0.0f, 1.0); |
| |
|
| | gl_TexCoord[3].xyzw = vec4(clamp(gl_Vertex.w*0.05, 0.0f, 1.0)); |
| | } |
| | else |
| | { |
| | gl_TexCoord[3].xyz = mix(colors[phase % 8].xyz*2.0, vec3(1.0), 0.1); |
| | } |
| |
|
| | gl_TexCoord[4].xyz = gl_Vertex.xyz; |
| | gl_TexCoord[5].xyz = viewPos.xyz; |
| | } |
| | ); |
| |
|
| | |
| | const char *fragmentPointShader = STRINGIFY( |
| |
|
| | uniform vec3 lightDir; |
| | uniform vec3 lightPos; |
| | uniform float spotMin; |
| | uniform float spotMax; |
| | uniform int mode; |
| |
|
| | uniform sampler2DShadow shadowTex; |
| | uniform vec2 shadowTaps[12]; |
| | uniform float pointRadius; |
| |
|
| | |
| | float shadowSample() |
| | { |
| | vec3 pos = vec3(gl_TexCoord[1].xyz/gl_TexCoord[1].w); |
| | vec3 uvw = (pos.xyz*0.5)+vec3(0.5); |
| |
|
| | |
| | if (uvw.x < 0.0 || uvw.x > 1.0) |
| | return 1.0; |
| | if (uvw.y < 0.0 || uvw.y > 1.0) |
| | return 1.0; |
| |
|
| | float s = 0.0; |
| | float radius = 0.002; |
| |
|
| | for (int i=0; i < 8; i++) |
| | { |
| | s += shadow2D(shadowTex, vec3(uvw.xy + shadowTaps[i]*radius, uvw.z)).r; |
| | } |
| |
|
| | s /= 8.0; |
| | return s; |
| | } |
| |
|
| | float sqr(float x) { return x*x; } |
| |
|
| | void main() |
| | { |
| | |
| | vec3 normal; |
| | normal.xy = gl_TexCoord[0].xy*vec2(2.0, -2.0) + vec2(-1.0, 1.0); |
| | float mag = dot(normal.xy, normal.xy); |
| | if (mag > 1.0) discard; |
| | normal.z = sqrt(1.0-mag); |
| |
|
| | if (mode == 2) |
| | { |
| | float alpha = normal.z*gl_TexCoord[3].w; |
| | gl_FragColor.xyz = gl_TexCoord[3].xyz*alpha; |
| | gl_FragColor.w = alpha; |
| | return; |
| | } |
| |
|
| | |
| | float shadow = shadowSample(); |
| |
|
| | vec3 lVec = normalize(gl_TexCoord[4].xyz-(lightPos)); |
| | vec3 lPos = vec3(gl_TexCoord[1].xyz/gl_TexCoord[1].w); |
| | float attenuation = max(smoothstep(spotMax, spotMin, dot(lPos.xy, lPos.xy)), 0.05); |
| |
|
| | vec3 diffuse = vec3(0.9, 0.9, 0.9); |
| | vec3 reflectance = gl_TexCoord[3].xyz; |
| |
|
| | vec3 Lo = diffuse*reflectance*max(0.0, sqr(-dot(gl_TexCoord[2].xyz, normal)*0.5 + 0.5))*max(0.2,shadow)*attenuation; |
| |
|
| | gl_FragColor = vec4(pow(Lo, vec3(1.0/2.2)), 1.0); |
| |
|
| | vec3 eyePos = gl_TexCoord[5].xyz + normal*pointRadius; |
| | vec4 ndcPos = gl_ProjectionMatrix * vec4(eyePos, 1.0); |
| | ndcPos.z /= ndcPos.w; |
| | gl_FragDepth = ndcPos.z*0.5 + 0.5; |
| | } |
| | ); |
| |
|
| | |
| | const char *vertexShader = "#version 130\n" STRINGIFY( |
| |
|
| | uniform mat4 lightTransform; |
| | uniform vec3 lightDir; |
| | uniform float bias; |
| | uniform vec4 clipPlane; |
| | uniform float expand; |
| |
|
| | uniform mat4 objectTransform; |
| |
|
| | void main() |
| | { |
| | vec3 n = normalize((objectTransform*vec4(gl_Normal, 0.0)).xyz); |
| | vec3 p = (objectTransform*vec4(gl_Vertex.xyz, 1.0)).xyz; |
| |
|
| | |
| | gl_Position = gl_ModelViewProjectionMatrix * vec4(p + expand*n, 1.0); |
| |
|
| | gl_TexCoord[0].xyz = n; |
| | gl_TexCoord[1] = lightTransform*vec4(p + n*bias, 1.0); |
| | gl_TexCoord[2] = gl_ModelViewMatrix*vec4(lightDir, 0.0); |
| | gl_TexCoord[3].xyz = p; |
| | gl_TexCoord[4] = gl_Color; |
| | gl_TexCoord[5] = gl_MultiTexCoord0; |
| | gl_TexCoord[6] = gl_SecondaryColor; |
| | gl_TexCoord[7] = gl_ModelViewMatrix*vec4(gl_Vertex.xyz, 1.0); |
| |
|
| | gl_ClipDistance[0] = dot(clipPlane,vec4(gl_Vertex.xyz, 1.0)); |
| | } |
| | ); |
| |
|
| | const char *passThroughShader = STRINGIFY( |
| |
|
| | void main() |
| | { |
| | gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); |
| |
|
| | } |
| | ); |
| |
|
| | |
| | const char *fragmentShader = STRINGIFY( |
| |
|
| | uniform vec3 lightDir; |
| | uniform vec3 lightPos; |
| | uniform float spotMin; |
| | uniform float spotMax; |
| | uniform vec3 color; |
| | uniform vec4 fogColor; |
| |
|
| | uniform sampler2DShadow shadowTex; |
| | uniform vec2 shadowTaps[12]; |
| |
|
| | uniform sampler2D tex; |
| | uniform bool sky; |
| |
|
| | uniform bool grid; |
| | uniform bool texture; |
| |
|
| | float sqr(float x) { return x*x; } |
| |
|
| | |
| | float shadowSample() |
| | { |
| | vec3 pos = vec3(gl_TexCoord[1].xyz/gl_TexCoord[1].w); |
| | vec3 uvw = (pos.xyz*0.5)+vec3(0.5); |
| |
|
| | |
| | if (uvw.x < 0.0 || uvw.x > 1.0) |
| | return 1.0; |
| | if (uvw.y < 0.0 || uvw.y > 1.0) |
| | return 1.0; |
| |
|
| | float s = 0.0; |
| | float radius = 0.002; |
| |
|
| | const int numTaps = 12; |
| |
|
| | for (int i=0; i < numTaps; i++) |
| | { |
| | s += shadow2D(shadowTex, vec3(uvw.xy + shadowTaps[i]*radius, uvw.z)).r; |
| | } |
| |
|
| | s /= numTaps; |
| | return s; |
| | } |
| |
|
| | float filterwidth(vec2 v) |
| | { |
| | vec2 fw = max(abs(dFdx(v)), abs(dFdy(v))); |
| | return max(fw.x, fw.y); |
| | } |
| |
|
| | vec2 bump(vec2 x) |
| | { |
| | return (floor((x)/2) + 2.f * max(((x)/2) - floor((x)/2) - .5f, 0.f)); |
| | } |
| |
|
| | float checker(vec2 uv) |
| | { |
| | float width = filterwidth(uv); |
| | vec2 p0 = uv - 0.5 * width; |
| | vec2 p1 = uv + 0.5 * width; |
| |
|
| | vec2 i = (bump(p1) - bump(p0)) / width; |
| | return i.x * i.y + (1 - i.x) * (1 - i.y); |
| | } |
| |
|
| | void main() |
| | { |
| | |
| | float shadow = max(shadowSample(), 0.5); |
| |
|
| | vec3 lVec = normalize(gl_TexCoord[3].xyz-(lightPos)); |
| | vec3 lPos = vec3(gl_TexCoord[1].xyz/gl_TexCoord[1].w); |
| | float attenuation = max(smoothstep(spotMax, spotMin, dot(lPos.xy, lPos.xy)), 0.05); |
| |
|
| | vec3 n = gl_TexCoord[0].xyz; |
| | vec3 color = gl_TexCoord[4].xyz; |
| |
|
| | if (!gl_FrontFacing) |
| | { |
| | color = gl_TexCoord[6].xyz; |
| | n *= -1.0f; |
| | } |
| |
|
| | if (grid && (n.y >0.995)) |
| | { |
| | color *= 1.0 - 0.25 * checker(vec2(gl_TexCoord[3].x, gl_TexCoord[3].z)); |
| | } |
| | else if (grid && abs(n.z) > 0.995) |
| | { |
| | color *= 1.0 - 0.25 * checker(vec2(gl_TexCoord[3].y, gl_TexCoord[3].x)); |
| | } |
| |
|
| | if (texture) |
| | { |
| | color = texture2D(tex, gl_TexCoord[5].xy).xyz; |
| | } |
| |
|
| | |
| | float wrap = 0.0; |
| | vec3 diffuse = color*vec3(1.0, 1.0, 1.0)*max(0.0, (-dot(lightDir, n)+wrap)/(1.0+wrap)*shadow)*attenuation; |
| |
|
| | |
| | vec3 light = vec3(0.03, 0.025, 0.025)*1.5; |
| | vec3 dark = vec3(0.025, 0.025, 0.03); |
| | vec3 ambient = 4.0*color*mix(dark, light, -dot(lightDir, n)*0.5 + 0.5)*attenuation; |
| |
|
| | vec3 fog = mix(vec3(fogColor), diffuse + ambient, exp(gl_TexCoord[7].z*fogColor.w)); |
| |
|
| | gl_FragColor = vec4(pow(fog, vec3(1.0/2.2)), 1.0); |
| | } |
| | ); |
| |
|
| | void ShadowApply(GLint sprogram, Vec3 lightPos, Vec3 lightTarget, Matrix44 lightTransform, GLuint shadowTex) |
| | { |
| | GLint uLightTransform = glGetUniformLocation(sprogram, "lightTransform"); |
| | glUniformMatrix4fv(uLightTransform, 1, false, lightTransform); |
| |
|
| | GLint uLightPos = glGetUniformLocation(sprogram, "lightPos"); |
| | glUniform3fv(uLightPos, 1, lightPos); |
| |
|
| | GLint uLightDir = glGetUniformLocation(sprogram, "lightDir"); |
| | glUniform3fv(uLightDir, 1, Normalize(lightTarget-lightPos)); |
| |
|
| | GLint uBias = glGetUniformLocation(sprogram, "bias"); |
| | glUniform1f(uBias, g_shadowBias); |
| |
|
| | const Vec2 taps[] = |
| | { |
| | Vec2(-0.326212f,-0.40581f),Vec2(-0.840144f,-0.07358f), |
| | Vec2(-0.695914f,0.457137f),Vec2(-0.203345f,0.620716f), |
| | Vec2(0.96234f,-0.194983f),Vec2(0.473434f,-0.480026f), |
| | Vec2(0.519456f,0.767022f),Vec2(0.185461f,-0.893124f), |
| | Vec2(0.507431f,0.064425f),Vec2(0.89642f,0.412458f), |
| | Vec2(-0.32194f,-0.932615f),Vec2(-0.791559f,-0.59771f) |
| | }; |
| |
|
| | GLint uShadowTaps = glGetUniformLocation(sprogram, "shadowTaps"); |
| | glUniform2fv(uShadowTaps, 12, &taps[0].x); |
| |
|
| | glEnable(GL_TEXTURE_2D); |
| | glActiveTexture(GL_TEXTURE0); |
| | glBindTexture(GL_TEXTURE_2D, shadowTex); |
| |
|
| | } |
| |
|
| | void DrawPoints(FluidRenderBuffers* buffersIn, int n, int offset, float radius, float screenWidth, float screenAspect, float fov, Vec3 lightPos, Vec3 lightTarget, Matrix44 lightTransform, ShadowMap* shadowMap, bool showDensity) |
| | { |
| | FluidRenderBuffersGL* buffers = reinterpret_cast<FluidRenderBuffersGL*>(buffersIn); |
| | GLuint positions = buffers->mPositionVBO; |
| | GLuint colors = buffers->mDensityVBO; |
| | GLuint indices = buffers->mIndices; |
| |
|
| | static int sprogram = -1; |
| | if (sprogram == -1) |
| | { |
| | sprogram = CompileProgram(vertexPointShader, fragmentPointShader); |
| | } |
| |
|
| | if (sprogram) |
| | { |
| | glEnable(GL_POINT_SPRITE); |
| | glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); |
| | glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); |
| | |
| | glEnable(GL_DEPTH_TEST); |
| |
|
| | int mode = 0; |
| | if (showDensity) |
| | mode = 1; |
| | if (shadowMap == NULL) |
| | mode = 2; |
| |
|
| | glVerify(glUseProgram(sprogram)); |
| | glVerify(glUniform1f( glGetUniformLocation(sprogram, "pointRadius"), radius)); |
| | glVerify(glUniform1f( glGetUniformLocation(sprogram, "pointScale"), screenWidth/screenAspect * (1.0f / (tanf(fov*0.5f))))); |
| | glVerify(glUniform1f( glGetUniformLocation(sprogram, "spotMin"), g_spotMin)); |
| | glVerify(glUniform1f( glGetUniformLocation(sprogram, "spotMax"), g_spotMax)); |
| | glVerify(glUniform1i( glGetUniformLocation(sprogram, "mode"), mode)); |
| | glVerify(glUniform4fv( glGetUniformLocation(sprogram, "colors"), 8, (float*)&g_colors[0].r)); |
| |
|
| | |
| | ShadowApply(sprogram, lightPos, lightTarget, lightTransform, shadowMap->texture); |
| |
|
| | glEnableClientState(GL_VERTEX_ARRAY); |
| | glBindBuffer(GL_ARRAY_BUFFER, positions); |
| | glVertexPointer(4, GL_FLOAT, 0, 0); |
| |
|
| | int d = glGetAttribLocation(sprogram, "density"); |
| | int p = glGetAttribLocation(sprogram, "phase"); |
| |
|
| | if (d != -1) |
| | { |
| | glVerify(glEnableVertexAttribArray(d)); |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, colors)); |
| | glVerify(glVertexAttribPointer(d, 1, GL_FLOAT, GL_FALSE, 0, 0)); |
| | } |
| |
|
| | if (p != -1) |
| | { |
| | glVerify(glEnableVertexAttribArray(p)); |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, colors)); |
| | glVerify(glVertexAttribIPointer(p, 1, GL_INT, 0, 0)); |
| | } |
| |
|
| | glVerify(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices)); |
| |
|
| | glVerify(glDrawElements(GL_POINTS, n, GL_UNSIGNED_INT, (const void*)(offset*sizeof(int)))); |
| |
|
| | glVerify(glUseProgram(0)); |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, 0)); |
| | glVerify(glDisableClientState(GL_VERTEX_ARRAY)); |
| |
|
| | if (d != -1) |
| | glVerify(glDisableVertexAttribArray(d)); |
| | if (p != -1) |
| | glVerify(glDisableVertexAttribArray(p)); |
| |
|
| | glDisable(GL_POINT_SPRITE); |
| | glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); |
| | } |
| | } |
| |
|
| | void DrawPlane(const Vec4& p); |
| |
|
| | static GLuint s_diffuseProgram = GLuint(-1); |
| | static GLuint s_shadowProgram = GLuint(-1); |
| |
|
| | #ifdef ANDROID |
| | void ResetProgramId() |
| | { |
| | s_diffuseProgram = GLuint(-1); |
| | s_shadowProgram = GLuint(-1); |
| | } |
| | #endif |
| |
|
| | static const int kShadowResolution = 2048; |
| |
|
| | ShadowMap* ShadowCreate() |
| | { |
| | GLuint texture; |
| | GLuint framebuffer; |
| |
|
| | glVerify(glGenFramebuffers(1, &framebuffer)); |
| | glVerify(glGenTextures(1, &texture)); |
| | glVerify(glBindTexture(GL_TEXTURE_2D, texture)); |
| |
|
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); |
| |
|
| | |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY)); |
| |
|
| | glVerify(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, kShadowResolution, kShadowResolution, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL)); |
| |
|
| | glVerify(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)); |
| |
|
| | glVerify(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture, 0)); |
| |
|
| | ShadowMap* map = new ShadowMap(); |
| | map->texture = texture; |
| | map->framebuffer = framebuffer; |
| |
|
| | return map; |
| |
|
| | } |
| |
|
| | void ShadowDestroy(ShadowMap* map) |
| | { |
| | glVerify(glDeleteTextures(1, &map->texture)); |
| | glVerify(glDeleteFramebuffers(1, &map->framebuffer)); |
| |
|
| | delete map; |
| | } |
| |
|
| | void ShadowBegin(ShadowMap* map) |
| | { |
| | glEnable(GL_POLYGON_OFFSET_FILL); |
| | glPolygonOffset(8.f, 8.f); |
| |
|
| | glVerify(glBindFramebuffer(GL_FRAMEBUFFER, map->framebuffer)); |
| |
|
| | glClearColor(0.0f, 0.0f, 0.0f, 0.0f); |
| | glClear(GL_DEPTH_BUFFER_BIT); |
| | glViewport(0, 0, kShadowResolution, kShadowResolution); |
| |
|
| | |
| | glDisable(GL_CULL_FACE); |
| |
|
| | |
| | if (s_shadowProgram == GLuint(-1)) |
| | s_shadowProgram = CompileProgram(vertexShader, passThroughShader); |
| |
|
| | glUseProgram(s_shadowProgram); |
| | glVerify(glUniformMatrix4fv(glGetUniformLocation(s_shadowProgram, "objectTransform"), 1, false, Matrix44::kIdentity)); |
| | } |
| |
|
| | void ShadowEnd() |
| | { |
| | glDisable(GL_POLYGON_OFFSET_FILL); |
| |
|
| | glVerify(glBindFramebuffer(GL_FRAMEBUFFER, g_msaaFbo)); |
| |
|
| | glEnable(GL_CULL_FACE); |
| | glUseProgram(0); |
| | } |
| |
|
| | void BindSolidShader(Vec3 lightPos, Vec3 lightTarget, Matrix44 lightTransform, ShadowMap* shadowMap, float bias, Vec4 fogColor) |
| | { |
| | glVerify(glViewport(0, 0, g_screenWidth, g_screenHeight)); |
| |
|
| | if (s_diffuseProgram == GLuint(-1)) |
| | s_diffuseProgram = CompileProgram(vertexShader, fragmentShader); |
| |
|
| | if (s_diffuseProgram) |
| | { |
| | glDepthMask(GL_TRUE); |
| | glEnable(GL_DEPTH_TEST); |
| |
|
| | glVerify(glUseProgram(s_diffuseProgram)); |
| | glVerify(glUniform1i(glGetUniformLocation(s_diffuseProgram, "grid"), 0)); |
| | glVerify(glUniform1f( glGetUniformLocation(s_diffuseProgram, "spotMin"), g_spotMin)); |
| | glVerify(glUniform1f( glGetUniformLocation(s_diffuseProgram, "spotMax"), g_spotMax)); |
| | glVerify(glUniform4fv( glGetUniformLocation(s_diffuseProgram, "fogColor"), 1, fogColor)); |
| |
|
| | glVerify(glUniformMatrix4fv( glGetUniformLocation(s_diffuseProgram, "objectTransform"), 1, false, Matrix44::kIdentity)); |
| |
|
| | |
| | ShadowApply(s_diffuseProgram, lightPos, lightTarget, lightTransform, shadowMap->texture); |
| | } |
| | } |
| |
|
| | void UnbindSolidShader() |
| | { |
| | glActiveTexture(GL_TEXTURE1); |
| | glDisable(GL_TEXTURE_2D); |
| | glActiveTexture(GL_TEXTURE0); |
| |
|
| | glUseProgram(0); |
| | } |
| |
|
| |
|
| | void SetMaterial(const Matrix44& xform, const RenderMaterial& mat) |
| | { |
| | GLint program; |
| | glGetIntegerv(GL_CURRENT_PROGRAM, &program); |
| |
|
| | if (program) |
| | { |
| | glUniformMatrix4fv( glGetUniformLocation(program, "objectTransform"), 1, false, xform); |
| |
|
| | const float maxSpecularPower = 2048.0f; |
| |
|
| | glVerify(glUniform1f(glGetUniformLocation(program, "specularPower"), powf(maxSpecularPower, 1.0f-mat.roughness))); |
| | glVerify(glUniform3fv(glGetUniformLocation(program, "specularColor"), 1, Lerp(Vec3(mat.specular*0.08f), mat.frontColor, mat.metallic))); |
| | glVerify(glUniform1f(glGetUniformLocation(program, "roughness"), mat.roughness)); |
| | glVerify(glUniform1f(glGetUniformLocation(program, "metallic"), mat.metallic)); |
| |
|
| | |
| | if (mat.colorTex) |
| | { |
| | GLuint tex = mat.colorTex->colorTex; |
| |
|
| | glActiveTexture(GL_TEXTURE1); |
| | glEnable(GL_TEXTURE_2D); |
| | glBindTexture(GL_TEXTURE_2D, tex); |
| |
|
| | glVerify(glUniform1i(glGetUniformLocation(program, "tex"), 1)); |
| | glVerify(glUniform1i(glGetUniformLocation(program, "texture"), 1)); |
| | } |
| | else |
| | { |
| | glVerify(glUniform1i(glGetUniformLocation(program, "tex"), 1)); |
| | glVerify(glUniform1i(glGetUniformLocation(program, "texture"), 0)); |
| | } |
| | } |
| |
|
| | glVerify(glColor3fv(mat.frontColor)); |
| | glVerify(glSecondaryColor3fv(mat.backColor)); |
| | } |
| |
|
| |
|
| | void DrawPlanes(Vec4* planes, int n, float bias) |
| | { |
| | |
| | glColor3f(0.9f, 0.9f, 0.9f); |
| |
|
| | GLint uBias = glGetUniformLocation(s_diffuseProgram, "bias"); |
| | glVerify(glUniform1f(uBias, 0.0f)); |
| | GLint uGrid = glGetUniformLocation(s_diffuseProgram, "grid"); |
| | glVerify(glUniform1i(uGrid, 1)); |
| | GLint uExpand = glGetUniformLocation(s_diffuseProgram, "expand"); |
| | glVerify(glUniform1f(uExpand, 0.0f)); |
| |
|
| | for (int i=0; i < n; ++i) |
| | { |
| | Vec4 p = planes[i]; |
| | p.w -= bias; |
| |
|
| | DrawPlane(p, false); |
| | } |
| |
|
| | glVerify(glUniform1i(uGrid, 0)); |
| | glVerify(glUniform1f(uBias, g_shadowBias)); |
| | } |
| |
|
| | void DrawMesh(const Mesh* m, Vec3 color) |
| | { |
| | if (m) |
| | { |
| | glVerify(glColor3fv(color)); |
| | glVerify(glSecondaryColor3fv(color)); |
| |
|
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, 0)); |
| | glVerify(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); |
| |
|
| | glVerify(glEnableClientState(GL_NORMAL_ARRAY)); |
| | glVerify(glEnableClientState(GL_VERTEX_ARRAY)); |
| |
|
| | glVerify(glNormalPointer(GL_FLOAT, sizeof(float) * 3, &m->m_normals[0])); |
| | glVerify(glVertexPointer(3, GL_FLOAT, sizeof(float) * 3, &m->m_positions[0])); |
| |
|
| | if (m->m_colours.size()) |
| | { |
| | glVerify(glEnableClientState(GL_COLOR_ARRAY)); |
| | glVerify(glColorPointer(4, GL_FLOAT, 0, &m->m_colours[0])); |
| | } |
| |
|
| | glVerify(glDrawElements(GL_TRIANGLES, m->GetNumFaces() * 3, GL_UNSIGNED_INT, &m->m_indices[0])); |
| |
|
| | glVerify(glDisableClientState(GL_VERTEX_ARRAY)); |
| | glVerify(glDisableClientState(GL_NORMAL_ARRAY)); |
| |
|
| | if (m->m_colours.size()) |
| | glVerify(glDisableClientState(GL_COLOR_ARRAY)); |
| | } |
| | } |
| |
|
| | void DrawCloth(const Vec4* positions, const Vec4* normals, const float* uvs, const int* indices, int numTris, int numPositions, int colorIndex, float expand, bool twosided, bool smooth) |
| | { |
| | if (!numTris) |
| | return; |
| |
|
| | if (twosided) |
| | glDisable(GL_CULL_FACE); |
| |
|
| | #if 1 |
| | GLint program; |
| | glGetIntegerv(GL_CURRENT_PROGRAM, &program); |
| |
|
| | if (program == GLint(s_diffuseProgram)) |
| | { |
| | GLint uBias = glGetUniformLocation(s_diffuseProgram, "bias"); |
| | glUniform1f(uBias, 0.0f); |
| |
|
| | GLint uExpand = glGetUniformLocation(s_diffuseProgram, "expand"); |
| | glUniform1f(uExpand, expand); |
| | } |
| | #endif |
| |
|
| | glColor3fv(g_colors[colorIndex+1]*1.5f); |
| | glSecondaryColor3fv(g_colors[colorIndex]*1.5f); |
| |
|
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, 0)); |
| | glVerify(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); |
| |
|
| | glVerify(glEnableClientState(GL_VERTEX_ARRAY)); |
| | glVerify(glEnableClientState(GL_NORMAL_ARRAY)); |
| |
|
| | glVerify(glVertexPointer(3, GL_FLOAT, sizeof(float)*4, positions)); |
| | glVerify(glNormalPointer(GL_FLOAT, sizeof(float)*4, normals)); |
| |
|
| | glVerify(glDrawElements(GL_TRIANGLES, numTris*3, GL_UNSIGNED_INT, indices)); |
| |
|
| | glVerify(glDisableClientState(GL_VERTEX_ARRAY)); |
| | glVerify(glDisableClientState(GL_NORMAL_ARRAY)); |
| |
|
| | if (twosided) |
| | glEnable(GL_CULL_FACE); |
| |
|
| | #if 1 |
| | if (program == GLint(s_diffuseProgram)) |
| | { |
| | GLint uBias = glGetUniformLocation(s_diffuseProgram, "bias"); |
| | glUniform1f(uBias, g_shadowBias); |
| |
|
| | GLint uExpand = glGetUniformLocation(s_diffuseProgram, "expand"); |
| | glUniform1f(uExpand, 0.0f); |
| | } |
| | #endif |
| | } |
| |
|
| | void DrawRope(Vec4* positions, int* indices, int numIndices, float radius, int color) |
| | { |
| | if (numIndices < 2) |
| | return; |
| |
|
| | std::vector<Vec3> vertices; |
| | std::vector<Vec3> normals; |
| | std::vector<int> triangles; |
| |
|
| | |
| | std::vector<Vec3> curve(numIndices); |
| | for (int i=0; i < numIndices; ++i) |
| | curve[i] = Vec3(positions[indices[i]]); |
| |
|
| | const int resolution = 8; |
| | const int smoothing = 3; |
| |
|
| | vertices.reserve(resolution*numIndices*smoothing); |
| | normals.reserve(resolution*numIndices*smoothing); |
| | triangles.reserve(numIndices*resolution*6*smoothing); |
| |
|
| | Extrude(&curve[0], int(curve.size()), vertices, normals, triangles, radius, resolution, smoothing); |
| |
|
| | glVerify(glDisable(GL_CULL_FACE)); |
| | glVerify(glColor3fv(g_colors[color%8]*1.5f)); |
| | glVerify(glSecondaryColor3fv(g_colors[color%8]*1.5f)); |
| |
|
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, 0)); |
| |
|
| | glVerify(glEnableClientState(GL_VERTEX_ARRAY)); |
| | glVerify(glEnableClientState(GL_NORMAL_ARRAY)); |
| |
|
| | glVerify(glVertexPointer(3, GL_FLOAT, sizeof(float)*3, &vertices[0])); |
| | glVerify(glNormalPointer(GL_FLOAT, sizeof(float)*3, &normals[0])); |
| |
|
| | glVerify(glDrawElements(GL_TRIANGLES, GLsizei(triangles.size()), GL_UNSIGNED_INT, &triangles[0])); |
| |
|
| | glVerify(glDisableClientState(GL_VERTEX_ARRAY)); |
| | glVerify(glDisableClientState(GL_NORMAL_ARRAY)); |
| | glVerify(glEnable(GL_CULL_FACE)); |
| |
|
| | } |
| |
|
| |
|
| | struct ReflectMap |
| | { |
| | GLuint texture; |
| |
|
| | int width; |
| | int height; |
| | }; |
| |
|
| | ReflectMap* ReflectCreate(int width, int height) |
| | { |
| | GLuint texture; |
| |
|
| | |
| | glVerify(glActiveTexture(GL_TEXTURE0)); |
| | glVerify(glEnable(GL_TEXTURE_2D)); |
| |
|
| | glVerify(glGenTextures(1, &texture)); |
| | glVerify(glBindTexture(GL_TEXTURE_2D, texture)); |
| |
|
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); |
| |
|
| | glVerify(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL)); |
| |
|
| | ReflectMap* map = new ReflectMap(); |
| | map->texture = texture; |
| | map->width = width; |
| | map->height = height; |
| |
|
| | return map; |
| | } |
| |
|
| | void ReflectDestroy(ReflectMap* map) |
| | { |
| | glVerify(glDeleteTextures(1, &map->texture)); |
| |
|
| | delete map; |
| | } |
| |
|
| | void ReflectBegin(ReflectMap* map, Vec4 plane, int width, int height) |
| | { |
| | glBindFramebuffer(GL_FRAMEBUFFER, 0); |
| | glViewport(0, 0, width, height); |
| |
|
| | glClearColor(0.0f, 0.0f, 0.0f, 0.0f); |
| | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
| |
|
| | Matrix44 scale = Matrix44::kIdentity; |
| | scale.columns[0][0] *= -2.0f; |
| | scale.columns[1][1] *= -2.0f; |
| | scale.columns[2][2] *= -2.0f; |
| | scale.columns[3][3] *= -2.0f; |
| |
|
| | Matrix44 reflect = (scale*Outer(Vec4(plane.x, plane.y, plane.z, 0.0f), plane)); |
| | reflect.columns[0][0] += 1.0f; |
| | reflect.columns[1][1] += 1.0f; |
| | reflect.columns[2][2] += 1.0f; |
| | reflect.columns[3][3] += 1.0f; |
| |
|
| | glMatrixMode(GL_MODELVIEW); |
| | glPushMatrix(); |
| | glMultMatrixf(reflect); |
| |
|
| | glVerify(glFrontFace(GL_CW)); |
| | glVerify(glEnable(GL_CLIP_PLANE0)); |
| |
|
| | glVerify(glUniform4fv( glGetUniformLocation(s_diffuseProgram, "clipPlane"), 1, plane)); |
| | } |
| |
|
| | void ReflectEnd(ReflectMap* map, int width, int height) |
| | { |
| | |
| | glVerify(glActiveTexture(GL_TEXTURE0)); |
| | glVerify(glEnable(GL_TEXTURE_2D)); |
| | glVerify(glBindTexture(GL_TEXTURE_2D, map->texture)); |
| |
|
| | glVerify(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, width, height)); |
| |
|
| | glMatrixMode(GL_MODELVIEW); |
| | glPopMatrix(); |
| |
|
| | glVerify(glDisable(GL_CLIP_PLANE0)); |
| | glVerify(glFrontFace(GL_CCW)); |
| |
|
| | glBindFramebuffer(GL_FRAMEBUFFER, g_msaaFbo); |
| |
|
| | glViewport(0, 0, g_screenWidth, g_screenHeight); |
| | } |
| |
|
| |
|
| | |
| | |
| |
|
| | const char *vertexPointDepthShader = STRINGIFY( |
| |
|
| | uniform float pointRadius; |
| | uniform float pointScale; |
| |
|
| | void main() |
| | { |
| | |
| | gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz, 1.0); |
| | gl_PointSize = pointScale * (pointRadius / gl_Position.w); |
| |
|
| | gl_TexCoord[0] = gl_MultiTexCoord0; |
| | gl_TexCoord[1] = gl_ModelViewMatrix * vec4(gl_Vertex.xyz, 1.0); |
| | } |
| | ); |
| |
|
| | |
| | const char *fragmentPointDepthShader = STRINGIFY( |
| |
|
| | uniform float pointRadius; |
| |
|
| | void main() |
| | { |
| | |
| | vec3 normal; |
| | normal.xy = gl_TexCoord[0].xy*vec2(2.0, -2.0) + vec2(-1.0, 1.0); |
| | float mag = dot(normal.xy, normal.xy); |
| | if (mag > 1.0) discard; |
| | normal.z = sqrt(1.0-mag); |
| |
|
| | vec3 eyePos = gl_TexCoord[1].xyz + normal*pointRadius*2.0; |
| | vec4 ndcPos = gl_ProjectionMatrix * vec4(eyePos, 1.0); |
| | ndcPos.z /= ndcPos.w; |
| |
|
| | gl_FragColor = vec4(eyePos.z, 1.0, 1.0, 1.0); |
| | gl_FragDepth = ndcPos.z*0.5 + 0.5; |
| | } |
| | ); |
| |
|
| |
|
| | |
| | const char *fragmentPointThicknessShader = STRINGIFY( |
| |
|
| | void main() |
| | { |
| | |
| | vec3 normal; |
| | normal.xy = gl_TexCoord[0].xy*vec2(2.0, -2.0) + vec2(-1.0, 1.0); |
| | float mag = dot(normal.xy, normal.xy); |
| | if (mag > 1.0) discard; |
| | normal.z = sqrt(1.0-mag); |
| |
|
| | gl_FragColor = vec4(normal.z*0.005); |
| | } |
| | ); |
| |
|
| | |
| | |
| | |
| | const char *vertexEllipsoidDepthShader = "#version 120\n" STRINGIFY( |
| |
|
| | |
| | attribute vec4 q1; |
| | attribute vec4 q2; |
| | attribute vec4 q3; |
| |
|
| | |
| | float Sign(float x) { return x < 0.0 ? -1.0: 1.0; } |
| |
|
| | bool solveQuadratic(float a, float b, float c, out float minT, out float maxT) |
| | { |
| | if (a == 0.0 && b == 0.0) |
| | { |
| | minT = maxT = 0.0; |
| | return false; |
| | } |
| |
|
| | float discriminant = b*b - 4.0*a*c; |
| |
|
| | if (discriminant < 0.0) |
| | { |
| | return false; |
| | } |
| |
|
| | float t = -0.5*(b + Sign(b)*sqrt(discriminant)); |
| | minT = t / a; |
| | maxT = c / t; |
| |
|
| | if (minT > maxT) |
| | { |
| | float tmp = minT; |
| | minT = maxT; |
| | maxT = tmp; |
| | } |
| |
|
| | return true; |
| | } |
| |
|
| | float DotInvW(vec4 a, vec4 b) { return a.x*b.x + a.y*b.y + a.z*b.z - a.w*b.w; } |
| |
|
| | void main() |
| | { |
| | vec3 worldPos = gl_Vertex.xyz; |
| |
|
| | |
| | mat4 q; |
| | q[0] = vec4(q1.xyz*q1.w, 0.0); |
| | q[1] = vec4(q2.xyz*q2.w, 0.0); |
| | q[2] = vec4(q3.xyz*q3.w, 0.0); |
| | q[3] = vec4(worldPos, 1.0); |
| |
|
| | |
| | mat4 invClip = transpose(gl_ModelViewProjectionMatrix*q); |
| |
|
| | |
| | float a1 = DotInvW(invClip[3], invClip[3]); |
| | float b1 = -2.0f*DotInvW(invClip[0], invClip[3]); |
| | float c1 = DotInvW(invClip[0], invClip[0]); |
| |
|
| | float xmin; |
| | float xmax; |
| | solveQuadratic(a1, b1, c1, xmin, xmax); |
| |
|
| | |
| | float a2 = DotInvW(invClip[3], invClip[3]); |
| | float b2 = -2.0f*DotInvW(invClip[1], invClip[3]); |
| | float c2 = DotInvW(invClip[1], invClip[1]); |
| |
|
| | float ymin; |
| | float ymax; |
| | solveQuadratic(a2, b2, c2, ymin, ymax); |
| |
|
| | gl_Position = vec4(worldPos.xyz, 1.0); |
| | gl_TexCoord[0] = vec4(xmin, xmax, ymin, ymax); |
| |
|
| | |
| | mat4 invq; |
| | invq[0] = vec4(q1.xyz/q1.w, 0.0); |
| | invq[1] = vec4(q2.xyz/q2.w, 0.0); |
| | invq[2] = vec4(q3.xyz/q3.w, 0.0); |
| | invq[3] = vec4(0.0, 0.0, 0.0, 1.0); |
| |
|
| | invq = transpose(invq); |
| | invq[3] = -(invq*gl_Position); |
| |
|
| | |
| | invq = invq*gl_ModelViewMatrixInverse; |
| |
|
| | |
| | gl_TexCoord[1] = invq[0]; |
| | gl_TexCoord[2] = invq[1]; |
| | gl_TexCoord[3] = invq[2]; |
| | gl_TexCoord[4] = invq[3]; |
| |
|
| | |
| | vec4 ndcPos = gl_ModelViewProjectionMatrix * vec4(worldPos.xyz, 1.0); |
| | gl_TexCoord[5] = ndcPos / ndcPos.w; |
| | } |
| | ); |
| |
|
| | const char* geometryEllipsoidDepthShader = |
| | "#version 120\n" |
| | "#extension GL_EXT_geometry_shader4 : enable\n" |
| | STRINGIFY( |
| | void main() |
| | { |
| | vec3 pos = gl_PositionIn[0].xyz; |
| | vec4 bounds = gl_TexCoordIn[0][0]; |
| | vec4 ndcPos = gl_TexCoordIn[0][5]; |
| |
|
| | |
| | const float ndcBound = 1.0; |
| | if (ndcPos.x < -ndcBound) return; |
| | if (ndcPos.x > ndcBound) return; |
| | if (ndcPos.y < -ndcBound) return; |
| | if (ndcPos.y > ndcBound) return; |
| |
|
| | float xmin = bounds.x; |
| | float xmax = bounds.y; |
| | float ymin = bounds.z; |
| | float ymax = bounds.w; |
| |
|
| | |
| | gl_TexCoord[0] = gl_TexCoordIn[0][1]; |
| | gl_TexCoord[1] = gl_TexCoordIn[0][2]; |
| | gl_TexCoord[2] = gl_TexCoordIn[0][3]; |
| | gl_TexCoord[3] = gl_TexCoordIn[0][4]; |
| |
|
| | gl_Position = vec4(xmin, ymax, 0.0, 1.0); |
| | EmitVertex(); |
| |
|
| | gl_Position = vec4(xmin, ymin, 0.0, 1.0); |
| | EmitVertex(); |
| |
|
| | gl_Position = vec4(xmax, ymax, 0.0, 1.0); |
| | EmitVertex(); |
| |
|
| | gl_Position = vec4(xmax, ymin, 0.0, 1.0); |
| | EmitVertex(); |
| | } |
| | ); |
| |
|
| | |
| | const char *fragmentEllipsoidDepthShader = "#version 120\n" STRINGIFY( |
| |
|
| | uniform vec3 invViewport; |
| | uniform vec3 invProjection; |
| |
|
| | float Sign(float x) { return x < 0.0 ? -1.0: 1.0; } |
| |
|
| | bool solveQuadratic(float a, float b, float c, out float minT, out float maxT) |
| | { |
| | if (a == 0.0 && b == 0.0) |
| | { |
| | minT = maxT = 0.0; |
| | return true; |
| | } |
| |
|
| | float discriminant = b*b - 4.0*a*c; |
| |
|
| | if (discriminant < 0.0) |
| | { |
| | return false; |
| | } |
| |
|
| | float t = -0.5*(b + Sign(b)*sqrt(discriminant)); |
| | minT = t / a; |
| | maxT = c / t; |
| |
|
| | if (minT > maxT) |
| | { |
| | float tmp = minT; |
| | minT = maxT; |
| | maxT = tmp; |
| | } |
| |
|
| | return true; |
| | } |
| |
|
| | float sqr(float x) { return x*x; } |
| |
|
| | void main() |
| | { |
| | |
| | mat4 invQuadric; |
| | invQuadric[0] = gl_TexCoord[0]; |
| | invQuadric[1] = gl_TexCoord[1]; |
| | invQuadric[2] = gl_TexCoord[2]; |
| | invQuadric[3] = gl_TexCoord[3]; |
| |
|
| | vec4 ndcPos = vec4(gl_FragCoord.xy*invViewport.xy*vec2(2.0, 2.0) - vec2(1.0, 1.0), -1.0, 1.0); |
| | vec4 viewDir = gl_ProjectionMatrixInverse*ndcPos; |
| |
|
| | |
| | vec4 dir = invQuadric*vec4(viewDir.xyz, 0.0); |
| | vec4 origin = invQuadric[3]; |
| |
|
| | |
| | float a = sqr(dir.x) + sqr(dir.y) + sqr(dir.z); |
| | float b = dir.x*origin.x + dir.y*origin.y + dir.z*origin.z - dir.w*origin.w; |
| | float c = sqr(origin.x) + sqr(origin.y) + sqr(origin.z) - sqr(origin.w); |
| |
|
| | float minT; |
| | float maxT; |
| |
|
| | if (solveQuadratic(a, 2.0*b, c, minT, maxT)) |
| | { |
| | vec3 eyePos = viewDir.xyz*minT; |
| | vec4 ndcPos = gl_ProjectionMatrix * vec4(eyePos, 1.0); |
| | ndcPos.z /= ndcPos.w; |
| |
|
| | gl_FragColor = vec4(eyePos.z, 1.0, 1.0, 1.0); |
| | gl_FragDepth = ndcPos.z*0.5 + 0.5; |
| |
|
| | return; |
| | } |
| | else |
| | discard; |
| |
|
| | gl_FragColor = vec4(0.5, 0.0, 0.0, 1.0); |
| | } |
| | ); |
| |
|
| | |
| | |
| |
|
| | const char* vertexPassThroughShader = STRINGIFY( |
| |
|
| | void main() |
| | { |
| | gl_Position = vec4(gl_Vertex.xyz, 1.0); |
| | gl_TexCoord[0] = gl_MultiTexCoord0; |
| | } |
| | ); |
| |
|
| | const char* fragmentBlurDepthShader = |
| | "#extension GL_ARB_texture_rectangle : enable\n" |
| | STRINGIFY( |
| |
|
| | uniform sampler2DRect depthTex; |
| | uniform sampler2D thicknessTex; |
| | uniform float blurRadiusWorld; |
| | uniform float blurScale; |
| | uniform float blurFalloff; |
| | uniform vec2 invTexScale; |
| |
|
| | uniform bool debug; |
| |
|
| | float sqr(float x) { return x*x; } |
| |
|
| | void main() |
| | { |
| | |
| | float depth = texture2DRect(depthTex, gl_FragCoord.xy).x; |
| | float thickness = texture2D(thicknessTex, gl_TexCoord[0].xy).x; |
| |
|
| | |
| | |
| |
|
| | if (debug) |
| | { |
| | |
| | gl_FragColor.x = depth; |
| | return; |
| | } |
| |
|
| | |
| | if (depth == 0.0) |
| | { |
| | gl_FragColor.x = 0.0; |
| | return; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | float blurDepthFalloff = 5.5; |
| |
|
| | float maxBlurRadius = 5.0; |
| | |
| | |
| |
|
| | |
| | |
| | float radius = min(maxBlurRadius, blurScale * (blurRadiusWorld / -depth)); |
| | float radiusInv = 1.0/radius; |
| | float taps = ceil(radius); |
| | float frac = taps - radius; |
| |
|
| | float sum = 0.0; |
| | float wsum = 0.0; |
| | float count = 0.0; |
| |
|
| | for(float y=-taps; y <= taps; y += 1.0) |
| | { |
| | for(float x=-taps; x <= taps; x += 1.0) |
| | { |
| | vec2 offset = vec2(x, y); |
| |
|
| | float sample = texture2DRect(depthTex, gl_FragCoord.xy + offset).x; |
| |
|
| | if (sample < -10000.0*0.5) |
| | continue; |
| |
|
| | |
| | float r1 = length(vec2(x, y))*radiusInv; |
| | float w = exp(-(r1*r1)); |
| |
|
| | |
| |
|
| | |
| | float r2 = (sample - depth) * blurDepthFalloff; |
| | float g = exp(-(r2*r2)); |
| |
|
| | |
| | float wBoundary = step(radius, max(abs(x), abs(y))); |
| | float wFrac = 1.0 - wBoundary*frac; |
| |
|
| | sum += sample * w * g * wFrac; |
| | wsum += w * g * wFrac; |
| | count += g * wFrac; |
| | } |
| | } |
| |
|
| | if (wsum > 0.0) { |
| | sum /= wsum; |
| | } |
| |
|
| | float blend = count/sqr(2.0*radius+1.0); |
| | gl_FragColor.x = mix(depth, sum, blend); |
| | } |
| | ); |
| |
|
| | const char* fragmentCompositeShader = STRINGIFY( |
| |
|
| | uniform sampler2D tex; |
| | uniform vec2 invTexScale; |
| | uniform vec3 lightPos; |
| | uniform vec3 lightDir; |
| | uniform float spotMin; |
| | uniform float spotMax; |
| | uniform vec4 color; |
| | uniform float ior; |
| |
|
| | uniform vec2 clipPosToEye; |
| |
|
| | uniform sampler2D reflectTex; |
| | uniform sampler2DShadow shadowTex; |
| | uniform vec2 shadowTaps[12]; |
| | uniform mat4 lightTransform; |
| |
|
| | uniform sampler2D thicknessTex; |
| | uniform sampler2D sceneTex; |
| |
|
| | uniform bool debug; |
| |
|
| | |
| | float shadowSample(vec3 worldPos, out float attenuation) |
| | { |
| | |
| | |
| | |
| |
|
| | vec4 pos = lightTransform*vec4(worldPos+lightDir*0.15, 1.0); |
| | pos /= pos.w; |
| | vec3 uvw = (pos.xyz*0.5)+vec3(0.5); |
| |
|
| | attenuation = max(smoothstep(spotMax, spotMin, dot(pos.xy, pos.xy)), 0.05); |
| |
|
| | |
| | if (uvw.x < 0.0 || uvw.x > 1.0) |
| | return 1.0; |
| | if (uvw.y < 0.0 || uvw.y > 1.0) |
| | return 1.0; |
| |
|
| | float s = 0.0; |
| | float radius = 0.002; |
| |
|
| | for (int i=0; i < 8; i++) |
| | { |
| | s += shadow2D(shadowTex, vec3(uvw.xy + shadowTaps[i]*radius, uvw.z)).r; |
| | } |
| |
|
| | s /= 8.0; |
| | return s; |
| | } |
| |
|
| | vec3 viewportToEyeSpace(vec2 coord, float eyeZ) |
| | { |
| | |
| | vec2 uv = (coord*2.0 - vec2(1.0))*clipPosToEye; |
| |
|
| | return vec3(-uv*eyeZ, eyeZ); |
| | } |
| |
|
| | vec3 srgbToLinear(vec3 c) { return pow(c, vec3(2.2)); } |
| | vec3 linearToSrgb(vec3 c) { return pow(c, vec3(1.0/2.2)); } |
| |
|
| | float sqr(float x) { return x*x; } |
| | float cube(float x) { return x*x*x; } |
| |
|
| | void main() |
| | { |
| | float eyeZ = texture2D(tex, gl_TexCoord[0].xy).x; |
| |
|
| | if (eyeZ == 0.0) |
| | discard; |
| |
|
| | |
| | vec3 eyePos = viewportToEyeSpace(gl_TexCoord[0].xy, eyeZ); |
| |
|
| | |
| | |
| | vec3 zl = eyePos - viewportToEyeSpace(gl_TexCoord[0].xy - vec2(invTexScale.x, 0.0), texture2D(tex, gl_TexCoord[0].xy - vec2(invTexScale.x, 0.0)).x); |
| | vec3 zr = viewportToEyeSpace(gl_TexCoord[0].xy + vec2(invTexScale.x, 0.0), texture2D(tex, gl_TexCoord[0].xy + vec2(invTexScale.x, 0.0)).x) - eyePos; |
| | vec3 zt = viewportToEyeSpace(gl_TexCoord[0].xy + vec2(0.0, invTexScale.y), texture2D(tex, gl_TexCoord[0].xy + vec2(0.0, invTexScale.y)).x) - eyePos; |
| | vec3 zb = eyePos - viewportToEyeSpace(gl_TexCoord[0].xy - vec2(0.0, invTexScale.y), texture2D(tex, gl_TexCoord[0].xy - vec2(0.0, invTexScale.y)).x); |
| |
|
| | vec3 dx = zl; |
| | vec3 dy = zt; |
| |
|
| | if (abs(zr.z) < abs(zl.z)) |
| | dx = zr; |
| |
|
| | if (abs(zb.z) < abs(zt.z)) |
| | dy = zb; |
| |
|
| | |
| | |
| |
|
| | vec4 worldPos = gl_ModelViewMatrixInverse*vec4(eyePos, 1.0); |
| |
|
| | float attenuation; |
| | float shadow = shadowSample(worldPos.xyz, attenuation); |
| |
|
| | vec3 l = (gl_ModelViewMatrix*vec4(lightDir, 0.0)).xyz; |
| | vec3 v = -normalize(eyePos); |
| |
|
| | vec3 n = normalize(cross(dx, dy)); |
| | vec3 h = normalize(v + l); |
| |
|
| | vec3 skyColor = vec3(0.1, 0.2, 0.4)*1.2; |
| | vec3 groundColor = vec3(0.1, 0.1, 0.2); |
| |
|
| | float fresnel = 0.1 + (1.0 - 0.1)*cube(1.0-max(dot(n, v), 0.0)); |
| |
|
| | vec3 lVec = normalize(worldPos.xyz-lightPos); |
| |
|
| | float ln = dot(l, n)*attenuation; |
| |
|
| | vec3 rEye = reflect(-v, n).xyz; |
| | vec3 rWorld = (gl_ModelViewMatrixInverse*vec4(rEye, 0.0)).xyz; |
| |
|
| | vec2 texScale = vec2(0.75, 1.0); |
| |
|
| | float refractScale = ior*0.025; |
| | float reflectScale = ior*0.1; |
| |
|
| | |
| | refractScale *= smoothstep(0.1, 0.4, worldPos.y); |
| |
|
| | vec2 refractCoord = gl_TexCoord[0].xy + n.xy*refractScale*texScale; |
| | |
| |
|
| | |
| | float thickness = max(texture2D(thicknessTex, refractCoord).x, 0.3); |
| |
|
| | |
| | vec3 transmission = (1.0-(1.0-color.xyz)*thickness*0.8)*color.w; |
| | vec3 refract = texture2D(sceneTex, refractCoord).xyz*transmission; |
| |
|
| | vec2 sceneReflectCoord = gl_TexCoord[0].xy - rEye.xy*texScale*reflectScale/eyePos.z; |
| | vec3 sceneReflect = (texture2D(sceneTex, sceneReflectCoord).xyz)*shadow; |
| |
|
| | vec3 planarReflect = texture2D(reflectTex, gl_TexCoord[0].xy).xyz; |
| | planarReflect = vec3(0.0); |
| |
|
| | |
| | vec3 reflect = mix(planarReflect, sceneReflect, smoothstep(0.05, 0.3, worldPos.y)) + mix(groundColor, skyColor, smoothstep(0.15, 0.25, rWorld.y)*shadow); |
| |
|
| | |
| | vec3 diffuse = color.xyz*mix(vec3(0.29, 0.379, 0.59), vec3(1.0), (ln*0.5 + 0.5)*max(shadow, 0.4))*(1.0-color.w); |
| | vec3 specular = vec3(1.2*pow(max(dot(h, n), 0.0), 400.0)); |
| |
|
| | gl_FragColor.xyz = diffuse + (mix(refract, reflect, fresnel) + specular)*color.w; |
| | gl_FragColor.w = 1.0; |
| |
|
| | if (debug) |
| | gl_FragColor = vec4(n*0.5 + vec3(0.5), 1.0); |
| |
|
| | |
| | vec4 clipPos = gl_ProjectionMatrix*vec4(0.0, 0.0, eyeZ, 1.0); |
| | clipPos.z /= clipPos.w; |
| |
|
| | gl_FragDepth = clipPos.z*0.5 + 0.5; |
| | } |
| | ); |
| |
|
| |
|
| | FluidRenderer* CreateFluidRenderer(uint32_t width, uint32_t height) |
| | { |
| | FluidRenderer* renderer = new FluidRenderer(); |
| |
|
| | renderer->mSceneWidth = width; |
| | renderer->mSceneHeight = height; |
| |
|
| | |
| | glVerify(glGenTextures(1, &renderer->mDepthTex)); |
| | glVerify(glBindTexture(GL_TEXTURE_RECTANGLE_ARB, renderer->mDepthTex)); |
| |
|
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); |
| | glVerify(glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE32F_ARB, width, height, 0, GL_LUMINANCE, GL_FLOAT, NULL)); |
| |
|
| | |
| | glVerify(glGenTextures(1, &renderer->mDepthSmoothTex)); |
| | glVerify(glBindTexture(GL_TEXTURE_2D, renderer->mDepthSmoothTex)); |
| |
|
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); |
| | glVerify(glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE32F_ARB, width, height, 0, GL_LUMINANCE, GL_FLOAT, NULL)); |
| |
|
| | |
| | glVerify(glGenTextures(1, &renderer->mSceneTex)); |
| | glVerify(glBindTexture(GL_TEXTURE_2D, renderer->mSceneTex)); |
| |
|
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); |
| | glVerify(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL)); |
| |
|
| | glVerify(glGenFramebuffers(1, &renderer->mSceneFbo)); |
| | glVerify(glBindFramebuffer(GL_FRAMEBUFFER, renderer->mSceneFbo)); |
| | glVerify(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderer->mSceneTex, 0)); |
| |
|
| | |
| | glVerify(glGenFramebuffers(1, &renderer->mDepthFbo)); |
| | glVerify(glBindFramebuffer(GL_FRAMEBUFFER, renderer->mDepthFbo)); |
| | glVerify(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, renderer->mDepthTex, 0)); |
| |
|
| | GLuint zbuffer; |
| | glVerify(glGenRenderbuffers(1, &zbuffer)); |
| | glVerify(glBindRenderbuffer(GL_RENDERBUFFER, zbuffer)); |
| | glVerify(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height)); |
| | glVerify(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, zbuffer)); |
| |
|
| | glVerify(glDrawBuffer(GL_COLOR_ATTACHMENT0)); |
| | glVerify(glReadBuffer(GL_COLOR_ATTACHMENT0)); |
| |
|
| | glCheckFramebufferStatus(GL_FRAMEBUFFER); |
| | glBindFramebuffer(GL_FRAMEBUFFER, g_msaaFbo); |
| |
|
| | |
| | glVerify(glGenTextures(1, &renderer->mReflectTex)); |
| | glVerify(glBindTexture(GL_TEXTURE_2D, renderer->mReflectTex)); |
| |
|
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); |
| | glVerify(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL)); |
| |
|
| | |
| | const int thicknessWidth = width; |
| | const int thicknessHeight = height; |
| |
|
| | glVerify(glGenTextures(1, &renderer->mThicknessTex)); |
| | glVerify(glBindTexture(GL_TEXTURE_2D, renderer->mThicknessTex)); |
| |
|
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); |
| |
|
| | #if USE_HDR_DIFFUSE_BLEND |
| | glVerify(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, thicknessWidth, thicknessHeight, 0, GL_RGBA, GL_FLOAT, NULL)); |
| | #else |
| | glVerify(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, thicknessWidth, thicknessHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL)); |
| | #endif |
| |
|
| | |
| | glVerify(glGenFramebuffers(1, &renderer->mThicknessFbo)); |
| | glVerify(glBindFramebuffer(GL_FRAMEBUFFER, renderer->mThicknessFbo)); |
| | glVerify(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderer->mThicknessTex, 0)); |
| |
|
| | GLuint thickz; |
| | glVerify(glGenRenderbuffers(1, &thickz)); |
| | glVerify(glBindRenderbuffer(GL_RENDERBUFFER, thickz)); |
| | glVerify(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, thicknessWidth, thicknessHeight)); |
| | glVerify(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, thickz)); |
| |
|
| | glCheckFramebufferStatus(GL_FRAMEBUFFER); |
| | glBindFramebuffer(GL_FRAMEBUFFER, g_msaaFbo); |
| |
|
| | |
| | |
| | renderer->mPointThicknessProgram = CompileProgram(vertexPointDepthShader, fragmentPointThicknessShader); |
| |
|
| | |
| | renderer->mEllipsoidDepthProgram = CompileProgram(vertexEllipsoidDepthShader, fragmentEllipsoidDepthShader, geometryEllipsoidDepthShader); |
| |
|
| | renderer->mCompositeProgram = CompileProgram(vertexPassThroughShader, fragmentCompositeShader); |
| | renderer->mDepthBlurProgram = CompileProgram(vertexPassThroughShader, fragmentBlurDepthShader); |
| |
|
| | return renderer; |
| | } |
| |
|
| | void DestroyFluidRenderer(FluidRenderer* renderer) |
| | { |
| | glVerify(glDeleteFramebuffers(1, &renderer->mSceneFbo)); |
| | glVerify(glDeleteFramebuffers(1, &renderer->mDepthFbo)); |
| | glVerify(glDeleteTextures(1, &renderer->mDepthTex)); |
| | glVerify(glDeleteTextures(1, &renderer->mDepthSmoothTex)); |
| | glVerify(glDeleteTextures(1, &renderer->mSceneTex)); |
| |
|
| | glVerify(glDeleteFramebuffers(1, &renderer->mThicknessFbo)); |
| | glVerify(glDeleteTextures(1, &renderer->mThicknessTex)); |
| | } |
| |
|
| | FluidRenderBuffers* CreateFluidRenderBuffers(int numFluidParticles, bool enableInterop) |
| | { |
| | FluidRenderBuffersGL* buffers = new FluidRenderBuffersGL(numFluidParticles); |
| |
|
| | |
| | glVerify(glGenBuffers(1, &buffers->mPositionVBO)); |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, buffers->mPositionVBO)); |
| | glVerify(glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 4 * numFluidParticles, 0, GL_DYNAMIC_DRAW)); |
| |
|
| | |
| | glVerify(glGenBuffers(1, &buffers->mDensityVBO)); |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, buffers->mDensityVBO)); |
| | glVerify(glBufferData(GL_ARRAY_BUFFER, sizeof(int)*numFluidParticles, 0, GL_DYNAMIC_DRAW)); |
| |
|
| | for (int i = 0; i < 3; ++i) |
| | { |
| | glVerify(glGenBuffers(1, &buffers->mAnisotropyVBO[i])); |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, buffers->mAnisotropyVBO[i])); |
| | glVerify(glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 4 * numFluidParticles, 0, GL_DYNAMIC_DRAW)); |
| | } |
| |
|
| | glVerify(glGenBuffers(1, &buffers->mIndices)); |
| | glVerify(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers->mIndices)); |
| | glVerify(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int)*numFluidParticles, 0, GL_DYNAMIC_DRAW)); |
| |
|
| | if (enableInterop) |
| | { |
| | buffers->mPositionBuf = NvFlexRegisterOGLBuffer(g_flexLib, buffers->mPositionVBO, numFluidParticles, sizeof(Vec4)); |
| | buffers->mDensitiesBuf = NvFlexRegisterOGLBuffer(g_flexLib, buffers->mDensityVBO, numFluidParticles, sizeof(float)); |
| | buffers->mIndicesBuf = NvFlexRegisterOGLBuffer(g_flexLib, buffers->mIndices, numFluidParticles, sizeof(int)); |
| |
|
| | buffers->mAnisotropyBuf[0] = NvFlexRegisterOGLBuffer(g_flexLib, buffers->mAnisotropyVBO[0], numFluidParticles, sizeof(Vec4)); |
| | buffers->mAnisotropyBuf[1] = NvFlexRegisterOGLBuffer(g_flexLib, buffers->mAnisotropyVBO[1], numFluidParticles, sizeof(Vec4)); |
| | buffers->mAnisotropyBuf[2] = NvFlexRegisterOGLBuffer(g_flexLib, buffers->mAnisotropyVBO[2], numFluidParticles, sizeof(Vec4)); |
| | } |
| |
|
| | return reinterpret_cast<FluidRenderBuffers*>(buffers); |
| | } |
| |
|
| | void DestroyFluidRenderBuffers(FluidRenderBuffers* buffers) |
| | { |
| | delete reinterpret_cast<FluidRenderBuffersGL*>(buffers); |
| | } |
| |
|
| | void UpdateFluidRenderBuffers(FluidRenderBuffers* buffersIn, NvFlexSolver* solver, bool anisotropy, bool density) |
| | { |
| | FluidRenderBuffersGL* buffers = reinterpret_cast<FluidRenderBuffersGL*>(buffersIn); |
| | |
| | |
| | if (!anisotropy) |
| | { |
| | |
| | NvFlexGetParticles(solver, buffers->mPositionBuf, NULL); |
| | } |
| | else |
| | { |
| | |
| | NvFlexGetSmoothParticles(solver, buffers->mPositionBuf, NULL); |
| | NvFlexGetAnisotropy(solver, buffers->mAnisotropyBuf[0], buffers->mAnisotropyBuf[1], buffers->mAnisotropyBuf[2], NULL); |
| | } |
| |
|
| | if (density) |
| | { |
| | NvFlexGetDensities(solver, buffers->mDensitiesBuf, NULL); |
| | } |
| | else |
| | { |
| | NvFlexGetPhases(solver, buffers->mDensitiesBuf, NULL); |
| | } |
| |
|
| | NvFlexGetActive(solver, buffers->mIndicesBuf, NULL); |
| | } |
| |
|
| | void UpdateFluidRenderBuffers(FluidRenderBuffers* buffersIn, Vec4* particles, float* densities, Vec4* anisotropy1, Vec4* anisotropy2, Vec4* anisotropy3, int numParticles, int* indices, int numIndices) |
| | { |
| | FluidRenderBuffersGL* buffers = reinterpret_cast<FluidRenderBuffersGL*>(buffersIn); |
| | |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, buffers->mPositionVBO)); |
| | glVerify(glBufferSubData(GL_ARRAY_BUFFER, 0, buffers->mNumParticles*sizeof(Vec4), particles)); |
| |
|
| | Vec4*const anisotropies[] = |
| | { |
| | anisotropy1, |
| | anisotropy2, |
| | anisotropy3, |
| | }; |
| |
|
| | for (int i = 0; i < 3; i++) |
| | { |
| | Vec4* anisotropy = anisotropies[i]; |
| | if (anisotropy) |
| | { |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, buffers->mAnisotropyVBO[i])); |
| | glVerify(glBufferSubData(GL_ARRAY_BUFFER, 0, buffers->mNumParticles * sizeof(Vec4), anisotropy)); |
| | } |
| | } |
| |
|
| | |
| | if (densities) |
| | { |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, buffers->mDensityVBO)); |
| | glVerify(glBufferSubData(GL_ARRAY_BUFFER, 0, buffers->mNumParticles*sizeof(float), densities)); |
| | } |
| |
|
| | if (indices) |
| | { |
| | glVerify(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers->mIndices)); |
| | glVerify(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, numIndices*sizeof(int), indices)); |
| | } |
| |
|
| | |
| | glVerify(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, 0)); |
| | } |
| |
|
| | DiffuseRenderBuffers* CreateDiffuseRenderBuffers(int numDiffuseParticles, bool& enableInterop) |
| | { |
| | DiffuseRenderBuffersGL* buffers = new DiffuseRenderBuffersGL(numDiffuseParticles); |
| |
|
| | if (numDiffuseParticles > 0) |
| | { |
| | glVerify(glGenBuffers(1, &buffers->mDiffusePositionVBO)); |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, buffers->mDiffusePositionVBO)); |
| | glVerify(glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 4 * numDiffuseParticles, 0, GL_DYNAMIC_DRAW)); |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, 0)); |
| |
|
| | glVerify(glGenBuffers(1, &buffers->mDiffuseVelocityVBO)); |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, buffers->mDiffuseVelocityVBO)); |
| | glVerify(glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 4 * numDiffuseParticles, 0, GL_DYNAMIC_DRAW)); |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, 0)); |
| |
|
| | if (enableInterop) |
| | { |
| | buffers->mDiffusePositionsBuf = NvFlexRegisterOGLBuffer(g_flexLib, buffers->mDiffusePositionVBO, numDiffuseParticles, sizeof(Vec4)); |
| | buffers->mDiffuseVelocitiesBuf = NvFlexRegisterOGLBuffer(g_flexLib, buffers->mDiffuseVelocityVBO, numDiffuseParticles, sizeof(Vec4)); |
| | } |
| | } |
| |
|
| | return reinterpret_cast<DiffuseRenderBuffers*>(buffers); |
| | } |
| |
|
| | void DestroyDiffuseRenderBuffers(DiffuseRenderBuffers* buffersIn) |
| | { |
| | DiffuseRenderBuffersGL* buffers = reinterpret_cast<DiffuseRenderBuffersGL*>(buffersIn); |
| | if (buffers->mNumParticles > 0) |
| | { |
| | glDeleteBuffers(1, &buffers->mDiffusePositionVBO); |
| | glDeleteBuffers(1, &buffers->mDiffuseVelocityVBO); |
| |
|
| | NvFlexUnregisterOGLBuffer(buffers->mDiffusePositionsBuf); |
| | NvFlexUnregisterOGLBuffer(buffers->mDiffuseVelocitiesBuf); |
| | } |
| | } |
| |
|
| | void UpdateDiffuseRenderBuffers(DiffuseRenderBuffers* buffersIn, NvFlexSolver* solver) |
| | { |
| | DiffuseRenderBuffersGL* buffers = reinterpret_cast<DiffuseRenderBuffersGL*>(buffersIn); |
| | |
| | if (buffers->mNumParticles) |
| | { |
| | NvFlexGetDiffuseParticles(solver, buffers->mDiffusePositionsBuf, buffers->mDiffuseVelocitiesBuf, NULL); |
| | } |
| | } |
| |
|
| | void UpdateDiffuseRenderBuffers(DiffuseRenderBuffers* buffersIn, Vec4* diffusePositions, Vec4* diffuseVelocities, int numDiffuseParticles) |
| | { |
| | DiffuseRenderBuffersGL* buffers = reinterpret_cast<DiffuseRenderBuffersGL*>(buffersIn); |
| | |
| | if (buffers->mNumParticles) |
| | { |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, buffers->mDiffusePositionVBO)); |
| | glVerify(glBufferSubData(GL_ARRAY_BUFFER, 0, buffers->mNumParticles*sizeof(Vec4), diffusePositions)); |
| |
|
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, buffers->mDiffuseVelocityVBO)); |
| | glVerify(glBufferSubData(GL_ARRAY_BUFFER, 0, buffers->mNumParticles*sizeof(Vec4), diffuseVelocities)); |
| | } |
| | } |
| |
|
| | void RenderFullscreenQuad() |
| | { |
| | glColor3f(1.0f, 1.0f, 1.0f); |
| | glBegin(GL_QUADS); |
| |
|
| | glTexCoord2f(0.0f, 0.0f); |
| | glVertex2f(-1.0f, -1.0f); |
| |
|
| | glTexCoord2f(1.0f, 0.0f); |
| | glVertex2f(1.0f, -1.0f); |
| |
|
| | glTexCoord2f(1.0f, 1.0f); |
| | glVertex2f(1.0f, 1.0f); |
| |
|
| | glTexCoord2f(0.0f, 1.0f); |
| | glVertex2f(-1.0f, 1.0f); |
| |
|
| | glEnd(); |
| | } |
| |
|
| | void RenderEllipsoids(FluidRenderer* render, FluidRenderBuffers* buffersIn, int n, int offset, float radius, float screenWidth, float screenAspect, float fov, Vec3 lightPos, Vec3 lightTarget, Matrix44 lightTransform, ShadowMap* shadowMap, Vec4 color, float blur, float ior, bool debug) |
| | { |
| | FluidRenderBuffersGL* buffers = reinterpret_cast<FluidRenderBuffersGL*>(buffersIn); |
| |
|
| | #if !ENABLE_SIMPLE_FLUID |
| | |
| | glVerify(glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, g_msaaFbo)); |
| | glVerify(glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, render->mSceneFbo)); |
| | glVerify(glBlitFramebuffer(0, 0, GLsizei(screenWidth), GLsizei(screenWidth/screenAspect), 0, 0, GLsizei(screenWidth), GLsizei(screenWidth/screenAspect), GL_COLOR_BUFFER_BIT, GL_LINEAR)); |
| | |
| | glVerify(glBindFramebuffer(GL_FRAMEBUFFER, render->mThicknessFbo)); |
| | glVerify(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, render->mThicknessTex, 0)); |
| | glVerify(glDrawBuffer(GL_COLOR_ATTACHMENT0)); |
| | glViewport(0, 0, GLsizei(screenWidth), GLsizei(screenWidth/screenAspect)); |
| | glClearColor(0.0f, 0.0f, 0.0f, 0.0f); |
| | glClear(GL_DEPTH_BUFFER_BIT); |
| |
|
| | glDepthMask(GL_TRUE); |
| | glDisable(GL_CULL_FACE); |
| |
|
| | if (g_mesh) |
| | OGL_Renderer::DrawMesh(g_mesh, Vec3(1.0f)); |
| |
|
| | DrawShapes(); |
| |
|
| | glClear(GL_COLOR_BUFFER_BIT); |
| |
|
| | glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); |
| | glEnable(GL_POINT_SPRITE); |
| | glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); |
| | glEnable(GL_DEPTH_TEST); |
| | glEnable(GL_BLEND); |
| | glBlendFunc(GL_ONE, GL_ONE); |
| | glDepthMask(GL_FALSE); |
| |
|
| | |
| | const float thicknessScale = 4.0f; |
| |
|
| | glUseProgram(render->mPointThicknessProgram); |
| | glUniform1f( glGetUniformLocation(render->mPointThicknessProgram, "pointRadius"), thicknessScale*radius); |
| | glUniform1f( glGetUniformLocation(render->mPointThicknessProgram, "pointScale"), screenWidth/screenAspect * (1.0f / (tanf(fov*0.5f)))); |
| |
|
| | glEnableClientState(GL_VERTEX_ARRAY); |
| | glBindBuffer(GL_ARRAY_BUFFER, buffers->mPositionVBO); |
| | glVertexPointer(3, GL_FLOAT, sizeof(float)*4, (void*)(offset*sizeof(float)*4)); |
| |
|
| | glDrawArrays(GL_POINTS, 0, n); |
| |
|
| | glUseProgram(0); |
| | glDisableClientState(GL_VERTEX_ARRAY); |
| | glDisable(GL_POINT_SPRITE); |
| | glDisable(GL_BLEND); |
| | #endif |
| |
|
| | |
| | glVerify(glBindFramebuffer(GL_FRAMEBUFFER, render->mDepthFbo)); |
| | glVerify(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, render->mDepthTex, 0)); |
| | glVerify(glDrawBuffer(GL_COLOR_ATTACHMENT0)); |
| |
|
| | |
| | |
| | glDisable(GL_POINT_SPRITE); |
| | glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); |
| | glEnable(GL_DEPTH_TEST); |
| | glDepthMask(GL_TRUE); |
| |
|
| | glViewport(0, 0, int(screenWidth), int(screenWidth/screenAspect)); |
| | glClearColor(0.0f, 0.0f, 0.0f, 0.0f); |
| | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
| |
|
| | const float viewHeight = tanf(fov/2.0f); |
| |
|
| | glUseProgram(render->mEllipsoidDepthProgram); |
| | glUniform3fv( glGetUniformLocation(render->mEllipsoidDepthProgram, "invViewport"), 1, Vec3(1.0f/screenWidth, screenAspect/screenWidth, 1.0f)); |
| | glUniform3fv( glGetUniformLocation(render->mEllipsoidDepthProgram, "invProjection"), 1, Vec3(screenAspect*viewHeight, viewHeight, 1.0f)); |
| |
|
| | glEnableClientState(GL_VERTEX_ARRAY); |
| | glBindBuffer(GL_ARRAY_BUFFER, buffers->mPositionVBO); |
| | glVertexPointer(3, GL_FLOAT, sizeof(float)*4, 0); |
| |
|
| | |
| | int s1 = glGetAttribLocation(render->mEllipsoidDepthProgram, "q1"); |
| | glEnableVertexAttribArray(s1); |
| | glBindBuffer(GL_ARRAY_BUFFER, buffers->mAnisotropyVBO[0]); |
| | glVertexAttribPointer(s1, 4, GL_FLOAT, GL_FALSE, 0, 0); |
| |
|
| | int s2 = glGetAttribLocation(render->mEllipsoidDepthProgram, "q2"); |
| | glEnableVertexAttribArray(s2); |
| | glBindBuffer(GL_ARRAY_BUFFER, buffers->mAnisotropyVBO[1]); |
| | glVertexAttribPointer(s2, 4, GL_FLOAT, GL_FALSE, 0, 0); |
| |
|
| | int s3 = glGetAttribLocation(render->mEllipsoidDepthProgram, "q3"); |
| | glEnableVertexAttribArray(s3); |
| | glBindBuffer(GL_ARRAY_BUFFER, buffers->mAnisotropyVBO[2]); |
| | glVertexAttribPointer(s3, 4, GL_FLOAT, GL_FALSE, 0, 0); |
| |
|
| | glVerify(glDrawArrays(GL_POINTS, offset, n)); |
| |
|
| | glUseProgram(0); |
| | glBindBuffer(GL_ARRAY_BUFFER, 0); |
| | glDisableClientState(GL_VERTEX_ARRAY); |
| | glDisableVertexAttribArray(s1); |
| | glDisableVertexAttribArray(s2); |
| | glDisableVertexAttribArray(s3); |
| |
|
| | glDisable(GL_POINT_SPRITE); |
| |
|
| | |
| | |
| |
|
| | glDisable(GL_DEPTH_TEST); |
| | glDepthMask(GL_FALSE); |
| |
|
| | glVerify(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, render->mDepthSmoothTex, 0)); |
| | glUseProgram(render->mDepthBlurProgram); |
| |
|
| | glActiveTexture(GL_TEXTURE0); |
| | glEnable(GL_TEXTURE_RECTANGLE_ARB); |
| | glBindTexture(GL_TEXTURE_RECTANGLE_ARB, render->mDepthTex); |
| |
|
| | glActiveTexture(GL_TEXTURE1); |
| | glEnable(GL_TEXTURE_2D); |
| | glBindTexture(GL_TEXTURE_2D, render->mThicknessTex); |
| |
|
| | glVerify(glUniform1f( glGetUniformLocation(render->mDepthBlurProgram, "blurRadiusWorld"), radius*0.5f)); |
| | glVerify(glUniform1f( glGetUniformLocation(render->mDepthBlurProgram, "blurScale"), screenWidth/screenAspect * (1.0f / (tanf(fov*0.5f))))); |
| | glVerify(glUniform2fv( glGetUniformLocation(render->mDepthBlurProgram, "invTexScale"), 1, Vec2(1.0f/screenAspect, 1.0f))); |
| | glVerify(glUniform1f( glGetUniformLocation(render->mDepthBlurProgram, "blurFalloff"), blur)); |
| | glVerify(glUniform1i( glGetUniformLocation(render->mDepthBlurProgram, "depthTex"), 0)); |
| | glVerify(glUniform1i( glGetUniformLocation(render->mDepthBlurProgram, "thicknessTex"), 1)); |
| | glVerify(glUniform1i(glGetUniformLocation(render->mDepthBlurProgram, "debug"), debug)); |
| |
|
| | glVerify(RenderFullscreenQuad()); |
| |
|
| | glActiveTexture(GL_TEXTURE0); |
| | glDisable(GL_TEXTURE_RECTANGLE_ARB); |
| |
|
| | |
| | |
| |
|
| | glVerify(glBindFramebuffer(GL_FRAMEBUFFER, g_msaaFbo)); |
| | glVerify(glEnable(GL_DEPTH_TEST)); |
| | glVerify(glDepthMask(GL_TRUE)); |
| | glVerify(glDisable(GL_BLEND)); |
| | glVerify(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); |
| |
|
| | glVerify(glUseProgram(render->mCompositeProgram)); |
| |
|
| | glVerify(glUniform2fv(glGetUniformLocation(render->mCompositeProgram, "invTexScale"), 1, Vec2(1.0f/screenWidth, screenAspect/screenWidth))); |
| | glVerify(glUniform2fv(glGetUniformLocation(render->mCompositeProgram, "clipPosToEye"), 1, Vec2(tanf(fov*0.5f)*screenAspect, tanf(fov*0.5f)))); |
| | glVerify(glUniform4fv(glGetUniformLocation(render->mCompositeProgram, "color"), 1, color)); |
| | glVerify(glUniform1f(glGetUniformLocation(render->mCompositeProgram, "ior"), ior)); |
| | glVerify(glUniform1f(glGetUniformLocation(render->mCompositeProgram, "spotMin"), g_spotMin)); |
| | glVerify(glUniform1f(glGetUniformLocation(render->mCompositeProgram, "spotMax"), g_spotMax)); |
| | glVerify(glUniform1i(glGetUniformLocation(render->mCompositeProgram, "debug"), debug)); |
| |
|
| | glVerify(glUniform3fv(glGetUniformLocation(render->mCompositeProgram, "lightPos"), 1, lightPos)); |
| | glVerify(glUniform3fv(glGetUniformLocation(render->mCompositeProgram, "lightDir"), 1, -Normalize(lightTarget-lightPos))); |
| | glVerify(glUniformMatrix4fv(glGetUniformLocation(render->mCompositeProgram, "lightTransform"), 1, false, lightTransform)); |
| |
|
| | const Vec2 taps[] = |
| | { |
| | Vec2(-0.326212f,-0.40581f),Vec2(-0.840144f,-0.07358f), |
| | Vec2(-0.695914f,0.457137f),Vec2(-0.203345f,0.620716f), |
| | Vec2(0.96234f,-0.194983f),Vec2(0.473434f,-0.480026f), |
| | Vec2(0.519456f,0.767022f),Vec2(0.185461f,-0.893124f), |
| | Vec2(0.507431f,0.064425f),Vec2(0.89642f,0.412458f), |
| | Vec2(-0.32194f,-0.932615f),Vec2(-0.791559f,-0.59771f) |
| | }; |
| |
|
| | glVerify(glUniform2fv(glGetUniformLocation(render->mCompositeProgram, "shadowTaps"), 12, &taps[0].x)); |
| |
|
| | |
| | glVerify(glActiveTexture(GL_TEXTURE0)); |
| | glVerify(glEnable(GL_TEXTURE_2D)); |
| | glVerify(glBindTexture(GL_TEXTURE_2D, render->mDepthSmoothTex)); |
| |
|
| | |
| | glVerify(glActiveTexture(GL_TEXTURE1)); |
| | glVerify(glEnable(GL_TEXTURE_2D)); |
| | glVerify(glBindTexture(GL_TEXTURE_2D, shadowMap->texture)); |
| |
|
| | |
| | glVerify(glActiveTexture(GL_TEXTURE2)); |
| | glVerify(glEnable(GL_TEXTURE_2D)); |
| | glVerify(glBindTexture(GL_TEXTURE_2D, render->mThicknessTex)); |
| |
|
| | |
| | glVerify(glActiveTexture(GL_TEXTURE3)); |
| | glVerify(glEnable(GL_TEXTURE_2D)); |
| | glVerify(glBindTexture(GL_TEXTURE_2D, render->mSceneTex)); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | glVerify(glUniform1i(glGetUniformLocation(render->mCompositeProgram, "tex"), 0)); |
| | glVerify(glUniform1i(glGetUniformLocation(render->mCompositeProgram, "shadowTex"), 1)); |
| | glVerify(glUniform1i(glGetUniformLocation(render->mCompositeProgram, "thicknessTex"), 2)); |
| | glVerify(glUniform1i(glGetUniformLocation(render->mCompositeProgram, "sceneTex"), 3)); |
| | glVerify(glUniform1i(glGetUniformLocation(render->mCompositeProgram, "reflectTex"), 5)); |
| |
|
| | |
| |
|
| | |
| | glVerify(RenderFullscreenQuad()); |
| |
|
| | |
| | glActiveTexture(GL_TEXTURE5); |
| | glDisable(GL_TEXTURE_2D); |
| | glActiveTexture(GL_TEXTURE3); |
| | glDisable(GL_TEXTURE_2D); |
| | glActiveTexture(GL_TEXTURE2); |
| | glDisable(GL_TEXTURE_2D); |
| | glActiveTexture(GL_TEXTURE1); |
| | glDisable(GL_TEXTURE_2D); |
| | glActiveTexture(GL_TEXTURE0); |
| | glDisable(GL_TEXTURE_2D); |
| |
|
| | glEnable(GL_DEPTH_TEST); |
| | glDepthMask(GL_TRUE); |
| | glDisable(GL_BLEND); |
| | } |
| |
|
| | |
| | |
| |
|
| | const char *vertexDiffuseShader = STRINGIFY( |
| |
|
| | uniform float pointRadius; |
| | uniform float pointScale; |
| | uniform vec3 lightPos; |
| | uniform vec3 lightDir; |
| | uniform mat4 lightTransform; |
| | uniform float spotMin; |
| | uniform float spotMax; |
| | uniform vec4 color; |
| |
|
| |
|
| | void main() |
| | { |
| | vec3 worldPos = gl_Vertex.xyz; |
| | vec4 eyePos = gl_ModelViewMatrix * vec4(worldPos, 1.0); |
| |
|
| | gl_Position = gl_ProjectionMatrix * eyePos; |
| | |
| |
|
| | |
| | gl_PointSize = pointRadius * (pointScale / gl_Position.w); |
| |
|
| | gl_TexCoord[0] = gl_MultiTexCoord0; |
| | gl_TexCoord[1] = vec4(worldPos, gl_Vertex.w); |
| | gl_TexCoord[2] = eyePos; |
| |
|
| | gl_TexCoord[3].xyz = gl_ModelViewMatrix*vec4(gl_MultiTexCoord1.xyz, 0.0); |
| | gl_TexCoord[4].xyzw = color; |
| |
|
| | |
| | if (gl_MultiTexCoord1.w == 2.0) |
| | gl_TexCoord[4].xyzw = vec4(0.85, 0.65, 0.65, color.w); |
| | else if (gl_MultiTexCoord1.w == 1.0) |
| | gl_TexCoord[4].xyzw = vec4(0.65, 0.85, 0.65, color.w); |
| |
|
| | |
| | vec4 ndcPos = gl_ModelViewProjectionMatrix * vec4(worldPos.xyz, 1.0); |
| | gl_TexCoord[5] = ndcPos / ndcPos.w; |
| | } |
| | ); |
| |
|
| |
|
| |
|
| |
|
| | const char *geometryDiffuseShader = |
| | "#version 120\n" |
| | "#extension GL_EXT_geometry_shader4 : enable\n" |
| | STRINGIFY( |
| |
|
| | uniform float pointScale; |
| | uniform float motionBlurScale; |
| | uniform float diffusion; |
| | uniform vec3 lightDir; |
| |
|
| | void main() |
| | { |
| | vec4 ndcPos = gl_TexCoordIn[0][5]; |
| |
|
| | |
| | const float ndcBound = 1.0; |
| | if (ndcPos.x < -ndcBound) return; |
| | if (ndcPos.x > ndcBound) return; |
| | if (ndcPos.y < -ndcBound) return; |
| | if (ndcPos.y > ndcBound) return; |
| |
|
| | float velocityScale = 1.0; |
| |
|
| | vec3 v = gl_TexCoordIn[0][3].xyz*velocityScale; |
| | vec3 p = gl_TexCoordIn[0][2].xyz; |
| |
|
| | |
| | vec3 u = vec3(0.0, pointScale, 0.0); |
| | vec3 l = vec3(pointScale, 0.0, 0.0); |
| |
|
| | |
| | float lifeFade = mix(1.0f+diffusion, 1.0, min(1.0, gl_TexCoordIn[0][1].w*0.25f)); |
| | u *= lifeFade; |
| | l *= lifeFade; |
| |
|
| | |
| |
|
| | float fade = 1.0/(lifeFade*lifeFade); |
| | float vlen = length(v)*motionBlurScale; |
| |
|
| | if (vlen > 0.5) |
| | { |
| | float len = max(pointScale, vlen*0.016); |
| | fade = min(1.0, 2.0/(len/pointScale)); |
| |
|
| | u = normalize(v)*max(pointScale, vlen*0.016); |
| | l = normalize(cross(u, vec3(0.0, 0.0, -1.0)))*pointScale; |
| | } |
| |
|
| | { |
| | gl_TexCoord[1] = gl_TexCoordIn[0][1]; |
| | gl_TexCoord[2] = gl_TexCoordIn[0][2]; |
| | gl_TexCoord[3] = gl_TexCoordIn[0][3]; |
| | gl_TexCoord[3].w = fade; |
| | gl_TexCoord[4] = gl_ModelViewMatrix*vec4(lightDir, 0.0); |
| | gl_TexCoord[4].w = gl_TexCoordIn[0][3].w; |
| | gl_TexCoord[5].xyzw = gl_TexCoordIn[0][4].xyzw; |
| |
|
| | float zbias = 0.0f; |
| |
|
| | gl_TexCoord[0] = vec4(0.0, 1.0, 0.0, 0.0); |
| | gl_Position = gl_ProjectionMatrix * vec4(p + u - l, 1.0); |
| | gl_Position.z -= zbias; |
| | EmitVertex(); |
| |
|
| | gl_TexCoord[0] = vec4(0.0, 0.0, 0.0, 0.0); |
| | gl_Position = gl_ProjectionMatrix * vec4(p - u - l, 1.0); |
| | gl_Position.z -= zbias; |
| | EmitVertex(); |
| |
|
| | gl_TexCoord[0] = vec4(1.0, 1.0, 0.0, 0.0); |
| | gl_Position = gl_ProjectionMatrix * vec4(p + u + l, 1.0); |
| | gl_Position.z -= zbias; |
| | EmitVertex(); |
| |
|
| | gl_TexCoord[0] = vec4(1.0, 0.0, 0.0, 0.0); |
| | gl_Position = gl_ProjectionMatrix * vec4(p - u + l, 1.0); |
| | gl_Position.z -= zbias; |
| | EmitVertex(); |
| | } |
| | } |
| | ); |
| |
|
| | const char *fragmentDiffuseShader = STRINGIFY( |
| |
|
| | float sqr(float x) { return x*x; } |
| | float cube(float x) { return x*x*x; } |
| |
|
| | uniform sampler2D depthTex; |
| | uniform sampler2D noiseTex; |
| | uniform vec2 invViewport; |
| | uniform vec4 color; |
| | uniform bool front; |
| | uniform bool shadow; |
| |
|
| | |
| | uniform sampler2D shadowTex; |
| | uniform vec2 shadowTaps[12]; |
| | uniform mat4 lightTransform; |
| | uniform vec3 lightDir; |
| | uniform float inscatterCoefficient; |
| | uniform float outscatterCoefficient; |
| |
|
| | void main() |
| | { |
| | float attenuation = gl_TexCoord[4].w; |
| | float lifeFade = min(1.0, gl_TexCoord[1].w*0.125); |
| |
|
| | |
| | vec3 normal; |
| | normal.xy = gl_TexCoord[0].xy*vec2(2.0, 2.0) + vec2(-1.0, -1.0); |
| | float mag = dot(normal.xy, normal.xy); |
| | if (mag > 1.0) discard; |
| | normal.z = 1.0-mag; |
| |
|
| | float velocityFade = gl_TexCoord[3].w; |
| | float alpha = lifeFade*velocityFade*sqr(normal.z); |
| |
|
| | gl_FragColor = alpha; |
| | } |
| | ); |
| |
|
| | int GetNumDiffuseRenderParticles(DiffuseRenderBuffers* buffers) |
| | { |
| | return reinterpret_cast<DiffuseRenderBuffersGL*>(buffers)->mNumParticles; |
| | } |
| |
|
| | void RenderDiffuse(FluidRenderer* render, DiffuseRenderBuffers* buffersIn, int n, float radius, float screenWidth, float screenAspect, float fov, Vec4 color, Vec3 lightPos, Vec3 lightTarget, Matrix44 lightTransform, ShadowMap* shadowMap, float motionBlur, float inscatter, float outscatter, bool shadow, bool front) |
| | { |
| | DiffuseRenderBuffersGL* buffers = reinterpret_cast<DiffuseRenderBuffersGL*>(buffersIn); |
| | static int sprogram = -1; |
| | if (sprogram == -1) |
| | sprogram = CompileProgram(vertexDiffuseShader, fragmentDiffuseShader, geometryDiffuseShader); |
| |
|
| | int thicknessScale = 1; |
| |
|
| | if (sprogram) |
| | { |
| | #if USE_HDR_DIFFUSE_BLEND |
| |
|
| | { |
| | glVerify(glBindFramebuffer(GL_READ_FRAMEBUFFER, g_msaaFbo)); |
| | glVerify(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, render->mThicknessFbo)); |
| | glVerify(glBlitFramebuffer(0, 0, render->mSceneWidth, render->mSceneHeight, 0, 0, render->mSceneWidth/thicknessScale, render->mSceneHeight/thicknessScale, GL_DEPTH_BUFFER_BIT, GL_NEAREST)); |
| |
|
| | glClearColor(0.0f, 0.0f, 0.0f, 0.0f); |
| | glClear(GL_COLOR_BUFFER_BIT); |
| | } |
| | #endif |
| |
|
| | glEnable(GL_POINT_SPRITE); |
| | glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); |
| | glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); |
| | glDepthMask(GL_FALSE); |
| | glEnable(GL_DEPTH_TEST); |
| | glEnable(GL_BLEND); |
| | glDisable(GL_CULL_FACE); |
| | glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); |
| |
|
| | glUseProgram(sprogram); |
| | glUniform1f( glGetUniformLocation(sprogram, "motionBlurScale"), motionBlur); |
| | glUniform1f( glGetUniformLocation(sprogram, "diffusion"), 1.0f); |
| | glUniform1f( glGetUniformLocation(sprogram, "pointScale"), radius*1.0f); |
| | glUniform1f( glGetUniformLocation(sprogram, "pointRadius"), screenWidth / float(thicknessScale) / (2.0f*screenAspect*tanf(fov*0.5f))); |
| | glUniform2fv( glGetUniformLocation(sprogram, "invViewport"), 1, Vec2(1.0f/screenWidth, screenAspect/screenWidth)); |
| | glUniform4fv( glGetUniformLocation(sprogram, "color"), 1, color); |
| | glUniform1i( glGetUniformLocation(sprogram, "tex"), 0); |
| | glUniform1f( glGetUniformLocation(sprogram, "inscatterCoefficient"), inscatter); |
| | glUniform1f( glGetUniformLocation(sprogram, "outscatterCoefficient"), outscatter); |
| |
|
| | GLint uLightTransform = glGetUniformLocation(sprogram, "lightTransform"); |
| | glUniformMatrix4fv(uLightTransform, 1, false, lightTransform); |
| |
|
| | GLint uLightPos = glGetUniformLocation(sprogram, "lightPos"); |
| | glUniform3fv(uLightPos, 1, lightPos); |
| |
|
| | GLint uLightDir = glGetUniformLocation(sprogram, "lightDir"); |
| | glUniform3fv(uLightDir, 1, Normalize(lightTarget-lightPos)); |
| |
|
| | glUniform1f( glGetUniformLocation(sprogram, "spotMin"), g_spotMin); |
| | glUniform1f( glGetUniformLocation(sprogram, "spotMax"), g_spotMax); |
| |
|
| | const Vec2 taps[] = |
| | { |
| | Vec2(-0.326212f,-0.40581f),Vec2(-0.840144f,-0.07358f), |
| | Vec2(-0.695914f,0.457137f),Vec2(-0.203345f,0.620716f), |
| | Vec2(0.96234f,-0.194983f),Vec2(0.473434f,-0.480026f), |
| | Vec2(0.519456f,0.767022f),Vec2(0.185461f,-0.893124f), |
| | Vec2(0.507431f,0.064425f),Vec2(0.89642f,0.412458f), |
| | Vec2(-0.32194f,-0.932615f),Vec2(-0.791559f,-0.59771f) |
| | }; |
| |
|
| | glVerify(glUniform2fv(glGetUniformLocation(sprogram, "shadowTaps"), 12, &taps[0].x)); |
| | glVerify(glUniform1i(glGetUniformLocation(sprogram, "noiseTex"), 2)); |
| | glVerify(glUniform1i(glGetUniformLocation(sprogram, "shadowTex"), 1)); |
| | glVerify(glUniform1i(glGetUniformLocation(sprogram, "depthTex"), 0)); |
| | glVerify(glUniform1i(glGetUniformLocation(sprogram, "front"), front)); |
| | glVerify(glUniform1i(glGetUniformLocation(sprogram, "shadow"), shadow)); |
| |
|
| | |
| | |
| | |
| | |
| |
|
| | |
| | glActiveTexture(GL_TEXTURE1); |
| | glEnable(GL_TEXTURE_2D); |
| | glBindTexture(GL_TEXTURE_2D, shadowMap->texture); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE)); |
| | |
| |
|
| |
|
| | glActiveTexture(GL_TEXTURE0); |
| | glEnable(GL_TEXTURE_2D); |
| | glBindTexture(GL_TEXTURE_2D, render->mDepthSmoothTex); |
| |
|
| | glClientActiveTexture(GL_TEXTURE1); |
| | glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, buffers->mDiffuseVelocityVBO)); |
| | glTexCoordPointer(4, GL_FLOAT, sizeof(float)*4, 0); |
| |
|
| | glEnableClientState(GL_VERTEX_ARRAY); |
| | glBindBuffer(GL_ARRAY_BUFFER, buffers->mDiffusePositionVBO); |
| | glVertexPointer(4, GL_FLOAT, sizeof(float)*4, 0); |
| |
|
| | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); |
| |
|
| | glDrawArrays(GL_POINTS, 0, n); |
| |
|
| | glUseProgram(0); |
| | glBindBuffer(GL_ARRAY_BUFFER, 0); |
| | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); |
| | glDisableClientState(GL_VERTEX_ARRAY); |
| | glDisableClientState(GL_TEXTURE_COORD_ARRAY); |
| | glDisable(GL_POINT_SPRITE); |
| | glDisable(GL_BLEND); |
| | glDepthMask(GL_TRUE); |
| |
|
| | glVerify(glActiveTexture(GL_TEXTURE2)); |
| | glVerify(glDisable(GL_TEXTURE_2D)); |
| | glVerify(glActiveTexture(GL_TEXTURE1)); |
| | glVerify(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE)); |
| | glVerify(glDisable(GL_TEXTURE_2D)); |
| | glVerify(glActiveTexture(GL_TEXTURE0)); |
| | glVerify(glDisable(GL_TEXTURE_2D)); |
| |
|
| | #if USE_HDR_DIFFUSE_BLEND |
| |
|
| | { |
| | glVerify(glBindFramebuffer(GL_FRAMEBUFFER, g_msaaFbo)); |
| | glVerify(glViewport(0, 0, int(screenWidth), int(screenWidth/screenAspect))); |
| |
|
| | |
| | glUseProgram(0); |
| | glDisable(GL_DEPTH_TEST); |
| | glEnable(GL_BLEND); |
| | glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); |
| | glDepthMask(GL_FALSE); |
| | glDisable(GL_CULL_FACE); |
| |
|
| | glVerify(glActiveTexture(GL_TEXTURE0)); |
| | glEnable(GL_TEXTURE_2D); |
| | glBindTexture(GL_TEXTURE_2D, render->mThicknessTex); |
| |
|
| | glMatrixMode(GL_MODELVIEW); |
| | glPushMatrix(); |
| | glLoadIdentity(); |
| |
|
| | glMatrixMode(GL_PROJECTION); |
| | glPushMatrix(); |
| | glLoadIdentity(); |
| | gluOrtho2D(-1.0f, 1.0f, -1.0f, 1.0); |
| |
|
| | RenderFullscreenQuad(); |
| |
|
| | glMatrixMode(GL_MODELVIEW); |
| | glPopMatrix(); |
| |
|
| | glMatrixMode(GL_PROJECTION); |
| | glPopMatrix(); |
| |
|
| | glDepthMask(GL_TRUE); |
| | } |
| | #endif |
| |
|
| | } |
| | } |
| |
|
| | GpuMesh* CreateGpuMesh(const Mesh* m) |
| | { |
| | GpuMesh* mesh = new GpuMesh(); |
| |
|
| | mesh->mNumVertices = m->GetNumVertices(); |
| | mesh->mNumFaces = m->GetNumFaces(); |
| |
|
| | |
| | glVerify(glGenBuffers(1, &mesh->mPositionsVBO)); |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, mesh->mPositionsVBO)); |
| | glVerify(glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*m->m_positions.size(), &m->m_positions[0], GL_STATIC_DRAW)); |
| |
|
| | glVerify(glGenBuffers(1, &mesh->mNormalsVBO)); |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, mesh->mNormalsVBO)); |
| | glVerify(glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*m->m_normals.size(), &m->m_normals[0], GL_STATIC_DRAW)); |
| |
|
| | glVerify(glGenBuffers(1, &mesh->mIndicesIBO)); |
| | glVerify(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->mIndicesIBO)); |
| | glVerify(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int)*m->m_indices.size(), &m->m_indices[0], GL_STATIC_DRAW)); |
| | glVerify(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); |
| |
|
| | return mesh; |
| | } |
| |
|
| | void DestroyGpuMesh(GpuMesh* m) |
| | { |
| | glVerify(glDeleteBuffers(1, &m->mPositionsVBO)); |
| | glVerify(glDeleteBuffers(1, &m->mNormalsVBO)); |
| | glVerify(glDeleteBuffers(1, &m->mIndicesIBO)); |
| | } |
| |
|
| | void DrawGpuMesh(GpuMesh* m, const Matrix44& xform, const Vec3& color) |
| | { |
| | if (m) |
| | { |
| | GLint program; |
| | glGetIntegerv(GL_CURRENT_PROGRAM, &program); |
| |
|
| | if (program) |
| | glUniformMatrix4fv( glGetUniformLocation(program, "objectTransform"), 1, false, xform); |
| |
|
| | glVerify(glColor3fv(color)); |
| | glVerify(glSecondaryColor3fv(color)); |
| |
|
| | glVerify(glEnableClientState(GL_VERTEX_ARRAY)); |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, m->mPositionsVBO)); |
| | glVerify(glVertexPointer(3, GL_FLOAT, sizeof(float)*3, 0)); |
| |
|
| | glVerify(glEnableClientState(GL_NORMAL_ARRAY)); |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, m->mNormalsVBO)); |
| | glVerify(glNormalPointer(GL_FLOAT, sizeof(float)*3, 0)); |
| |
|
| | glVerify(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->mIndicesIBO)); |
| |
|
| | glVerify(glDrawElements(GL_TRIANGLES, m->mNumFaces*3, GL_UNSIGNED_INT, 0)); |
| |
|
| | glVerify(glDisableClientState(GL_VERTEX_ARRAY)); |
| | glVerify(glDisableClientState(GL_NORMAL_ARRAY)); |
| |
|
| | glVerify(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, 0)); |
| |
|
| | if (program) |
| | glUniformMatrix4fv(glGetUniformLocation(program, "objectTransform"), 1, false, Matrix44::kIdentity); |
| | } |
| | } |
| |
|
| | void DrawGpuMeshInstances(GpuMesh* m, const Matrix44* xforms, int n, const Vec3& color) |
| | { |
| | if (m) |
| | { |
| | GLint program; |
| | glGetIntegerv(GL_CURRENT_PROGRAM, &program); |
| |
|
| | GLint param = glGetUniformLocation(program, "objectTransform"); |
| |
|
| | glVerify(glColor3fv(color)); |
| | glVerify(glSecondaryColor3fv(color)); |
| |
|
| | glVerify(glEnableClientState(GL_VERTEX_ARRAY)); |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, m->mPositionsVBO)); |
| | glVerify(glVertexPointer(3, GL_FLOAT, sizeof(float)*3, 0)); |
| |
|
| | glVerify(glEnableClientState(GL_NORMAL_ARRAY)); |
| | glVerify(glBindBuffer(GL_ARRAY_BUFFER, m->mNormalsVBO)); |
| | glVerify(glNormalPointer(GL_FLOAT, sizeof(float)*3, 0)); |
| |
|
| | glVerify(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->mIndicesIBO)); |
| |
|
| | for (int i=0; i < n; ++i) |
| | { |
| | if (program) |
| | glUniformMatrix4fv( param, 1, false, xforms[i]); |
| |
|
| | glVerify(glDrawElements(GL_TRIANGLES, m->mNumFaces*3, GL_UNSIGNED_INT, 0)); |
| | } |
| |
|
| | glVerify(glDisableClientState(GL_VERTEX_ARRAY)); |
| | glVerify(glDisableClientState(GL_NORMAL_ARRAY)); |
| |
|
| | glVerify(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); |
| | } |
| | } |
| |
|
| | void BeginLines() |
| | { |
| | glUseProgram(0); |
| | glDisable(GL_DEPTH_TEST); |
| | glDisable(GL_BLEND); |
| |
|
| | glLineWidth(1.0f); |
| |
|
| | for (int i = 0; i < 8; ++i) |
| | { |
| | glActiveTexture(GL_TEXTURE0 + i); |
| | glDisable(GL_TEXTURE_2D); |
| | } |
| |
|
| | glBegin(GL_LINES); |
| | } |
| |
|
| | void DrawLine(const Vec3& p, const Vec3& q, const Vec4& color) |
| | { |
| | glColor4fv(color); |
| | glVertex3fv(p); |
| | glVertex3fv(q); |
| | } |
| |
|
| | void EndLines() |
| | { |
| | glEnd(); |
| | } |
| |
|
| | void BeginPoints(float size) |
| | { |
| | glPointSize(size); |
| |
|
| | glUseProgram(0); |
| | glDisable(GL_DEPTH_TEST); |
| | glDisable(GL_BLEND); |
| |
|
| | glEnable(GL_BLEND); |
| | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
| | glEnable(GL_POINT_SPRITE); |
| | glEnable(GL_POINT_SMOOTH); |
| | glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); |
| |
|
| | for (int i = 0; i < 8; ++i) |
| | { |
| | glActiveTexture(GL_TEXTURE0 + i); |
| | glDisable(GL_TEXTURE_2D); |
| | } |
| |
|
| | glBegin(GL_POINTS); |
| | } |
| |
|
| | void DrawPoint(const Vec3& p, const Vec4& color) |
| | { |
| | glColor3fv(color); |
| | glVertex3fv(p); |
| | } |
| |
|
| | void EndPoints() |
| | { |
| | glEnd(); |
| | } |
| |
|
| | float SyncAndGetRenderTime(unsigned long long* begin, unsigned long long* end, unsigned long long* freq) |
| | { |
| | *begin = 0; |
| | *end = 0; |
| | *freq = 1; |
| | return 0.0f; |
| | } |
| |
|
| | float RendererGetDeviceTimestamps(unsigned long long* begin, unsigned long long* end, unsigned long long* freq) { return 0.0f; } |
| | void* GetGraphicsCommandQueue() { return nullptr; } |
| | void GraphicsTimerBegin() { } |
| | void GraphicsTimerEnd() { } |
| |
|
| | void StartGpuWork() { } |
| | void EndGpuWork() { } |
| |
|
| | void GetRenderDevice(void** deviceOut, void** contextOut) |
| | { |
| | *deviceOut = nullptr; |
| | *contextOut = nullptr; |
| | } |
| |
|
| | void DrawImguiGraph() |
| | { |
| | imguiGraphDraw(); |
| | } |
| |
|
| | } |
| |
|
| |
|
| | #include "../demoContext.h" |
| | #include "demoContextOGL.h" |
| |
|
| | DemoContext* CreateDemoContextOGL() |
| | { |
| | return new DemoContextOGL; |
| | } |
| |
|
| | bool DemoContextOGL::initialize(const RenderInitOptions& options) |
| | { |
| | OGL_Renderer::InitRender(options); |
| | return true; |
| | } |
| |
|
| | void DemoContextOGL::startFrame(Vec4 colorIn) |
| | { |
| | OGL_Renderer::StartFrame(colorIn); |
| | } |
| |
|
| | void DemoContextOGL::endFrame() |
| | { |
| | OGL_Renderer::EndFrame(); |
| | } |
| |
|
| | void DemoContextOGL::presentFrame(bool fullsync) |
| | { |
| | OGL_Renderer::PresentFrame(fullsync); |
| | } |
| |
|
| | void DemoContextOGL::readFrame(int* buffer, int width, int height) |
| | { |
| | OGL_Renderer::ReadFrame(buffer, width, height); |
| | } |
| |
|
| | void DemoContextOGL::getViewRay(int x, int y, Vec3& origin, Vec3& dir) |
| | { |
| | OGL_Renderer::GetViewRay(x, y, origin, dir); |
| | } |
| |
|
| | void DemoContextOGL::setView(Matrix44 view, Matrix44 projection) |
| | { |
| | OGL_Renderer::SetView(view, projection); |
| | } |
| |
|
| | void DemoContextOGL::renderEllipsoids(FluidRenderer* renderer, FluidRenderBuffers* buffers, int n, int offset, float radius, float screenWidth, float screenAspect, float fov, Vec3 lightPos, Vec3 lightTarget, Matrix44 lightTransform, ::ShadowMap* shadowMap, Vec4 color, float blur, float ior, bool debug) |
| | { |
| | OGL_Renderer::RenderEllipsoids(renderer, buffers, n, offset, radius, screenWidth, screenAspect, fov, lightPos, lightTarget, lightTransform, shadowMap, color, blur, ior, debug); |
| | } |
| |
|
| | void DemoContextOGL::drawMesh(const Mesh* m, Vec3 color) |
| | { |
| | OGL_Renderer::DrawMesh(m, color); |
| | } |
| |
|
| | void DemoContextOGL::drawCloth(const Vec4* positions, const Vec4* normals, const float* uvs, const int* indices, int numTris, int numPositions, int colorIndex, float expand, bool twosided, bool smooth) |
| | { |
| | OGL_Renderer::DrawCloth(positions, normals, uvs, indices, numTris, numPositions, colorIndex, expand, twosided, smooth); |
| | } |
| |
|
| | void DemoContextOGL::drawRope(Vec4* positions, int* indices, int numIndices, float radius, int color) |
| | { |
| | OGL_Renderer::DrawRope(positions, indices, numIndices, radius, color); |
| | } |
| |
|
| | void DemoContextOGL::drawPlane(const Vec4& p, bool color) |
| | { |
| | OGL_Renderer::DrawPlane(p, color); |
| | } |
| |
|
| | void DemoContextOGL::drawPlanes(Vec4* planes, int n, float bias) |
| | { |
| | OGL_Renderer::DrawPlanes(planes, n, bias); |
| | } |
| |
|
| | void DemoContextOGL::drawPoints(FluidRenderBuffers* buffers, int n, int offset, float radius, float screenWidth, float screenAspect, float fov, Vec3 lightPos, Vec3 lightTarget, Matrix44 lightTransform, ::ShadowMap* shadowTex, bool showDensity) |
| | { |
| | OGL_Renderer::DrawPoints(buffers, n, offset, radius, screenWidth, screenAspect, fov, lightPos, lightTarget, lightTransform, shadowTex, showDensity); |
| | } |
| |
|
| | void DemoContextOGL::graphicsTimerBegin() |
| | { |
| | OGL_Renderer::GraphicsTimerBegin(); |
| | } |
| |
|
| | void DemoContextOGL::graphicsTimerEnd() |
| | { |
| | OGL_Renderer::GraphicsTimerEnd(); |
| | } |
| |
|
| | float DemoContextOGL::rendererGetDeviceTimestamps(unsigned long long* begin, unsigned long long* end, unsigned long long* freq) |
| | { |
| | return OGL_Renderer::RendererGetDeviceTimestamps(begin, end, freq); |
| | } |
| |
|
| | void DemoContextOGL::bindSolidShader(Vec3 lightPos, Vec3 lightTarget, Matrix44 lightTransform, ::ShadowMap* shadowMap, float bias, Vec4 fogColor) |
| | { |
| | OGL_Renderer::BindSolidShader(lightPos, lightTarget, lightTransform, shadowMap, bias, fogColor); |
| | } |
| |
|
| | void DemoContextOGL::unbindSolidShader() |
| | { |
| | OGL_Renderer::UnbindSolidShader(); |
| | } |
| |
|
| | ShadowMap* DemoContextOGL::shadowCreate() |
| | { |
| | return OGL_Renderer::ShadowCreate(); |
| | } |
| |
|
| | void DemoContextOGL::shadowDestroy(ShadowMap* map) |
| | { |
| | OGL_Renderer::ShadowDestroy(map); |
| | } |
| |
|
| | void DemoContextOGL::shadowBegin(ShadowMap* map) |
| | { |
| | OGL_Renderer::ShadowBegin(map); |
| | } |
| |
|
| | void DemoContextOGL::shadowEnd() |
| | { |
| | OGL_Renderer::ShadowEnd(); |
| | } |
| |
|
| | FluidRenderer* DemoContextOGL::createFluidRenderer(uint32_t width, uint32_t height) |
| | { |
| | return OGL_Renderer::CreateFluidRenderer(width, height); |
| | } |
| |
|
| | void DemoContextOGL::destroyFluidRenderer(FluidRenderer* renderer) |
| | { |
| | OGL_Renderer::DestroyFluidRenderer(renderer); |
| | } |
| |
|
| | FluidRenderBuffers* DemoContextOGL::createFluidRenderBuffers(int numParticles, bool enableInterop) |
| | { |
| | return OGL_Renderer::CreateFluidRenderBuffers(numParticles, enableInterop); |
| | } |
| |
|
| | void DemoContextOGL::updateFluidRenderBuffers(FluidRenderBuffers* buffers, NvFlexSolver* flex, bool anisotropy, bool density) |
| | { |
| | OGL_Renderer::UpdateFluidRenderBuffers(buffers, flex, anisotropy, density); |
| | } |
| |
|
| | void DemoContextOGL::updateFluidRenderBuffers(FluidRenderBuffers* buffers, Vec4* particles, float* densities, Vec4* anisotropy1, Vec4* anisotropy2, Vec4* anisotropy3, int numParticles, int* indices, int numIndices) |
| | { |
| | OGL_Renderer::UpdateFluidRenderBuffers(buffers, particles, densities, anisotropy1, anisotropy2, anisotropy3, numParticles, indices, numIndices); |
| | } |
| |
|
| | void DemoContextOGL::destroyFluidRenderBuffers(FluidRenderBuffers* buffers) |
| | { |
| | OGL_Renderer::DestroyFluidRenderBuffers(buffers); |
| | } |
| |
|
| | GpuMesh* DemoContextOGL::createGpuMesh(const Mesh* m) |
| | { |
| | return OGL_Renderer::CreateGpuMesh(m); |
| | } |
| |
|
| | void DemoContextOGL::destroyGpuMesh(GpuMesh* mesh) |
| | { |
| | OGL_Renderer::DestroyGpuMesh(mesh); |
| | } |
| |
|
| | void DemoContextOGL::drawGpuMesh(GpuMesh* m, const Matrix44& xform, const Vec3& color) |
| | { |
| | OGL_Renderer::DrawGpuMesh(m, xform, color); |
| | } |
| |
|
| | void DemoContextOGL::drawGpuMeshInstances(GpuMesh* m, const Matrix44* xforms, int n, const Vec3& color) |
| | { |
| | OGL_Renderer::DrawGpuMeshInstances(m, xforms, n, color); |
| | } |
| |
|
| | DiffuseRenderBuffers* DemoContextOGL::createDiffuseRenderBuffers(int numDiffuseParticles, bool& enableInterop) |
| | { |
| | return OGL_Renderer::CreateDiffuseRenderBuffers(numDiffuseParticles, enableInterop); |
| | } |
| |
|
| | void DemoContextOGL::destroyDiffuseRenderBuffers(DiffuseRenderBuffers* buffers) |
| | { |
| | OGL_Renderer::DestroyDiffuseRenderBuffers(buffers); |
| | } |
| |
|
| | void DemoContextOGL::updateDiffuseRenderBuffers(DiffuseRenderBuffers* buffers, Vec4* diffusePositions, Vec4* diffuseVelocities, int numDiffuseParticles) |
| | { |
| | OGL_Renderer::UpdateDiffuseRenderBuffers(buffers, diffusePositions, diffuseVelocities, numDiffuseParticles); |
| | } |
| |
|
| | void DemoContextOGL::updateDiffuseRenderBuffers(DiffuseRenderBuffers* buffers, NvFlexSolver* solver) |
| | { |
| | OGL_Renderer::UpdateDiffuseRenderBuffers(buffers, solver); |
| | } |
| |
|
| | void DemoContextOGL::drawDiffuse(FluidRenderer* render, const DiffuseRenderBuffers* buffers, int n, float radius, float screenWidth, float screenAspect, float fov, Vec4 color, Vec3 lightPos, Vec3 lightTarget, Matrix44 lightTransform, ::ShadowMap* shadowMap, float motionBlur, float inscatter, float outscatter, bool shadowEnabled, bool front) |
| | { |
| | OGL_Renderer::RenderDiffuse(render, (DiffuseRenderBuffers*)buffers, n, radius, screenWidth, screenAspect, fov, color, lightPos, lightTarget, lightTransform, shadowMap, motionBlur, inscatter, outscatter, shadowEnabled, front); |
| | } |
| |
|
| | int DemoContextOGL::getNumDiffuseRenderParticles(DiffuseRenderBuffers* buffers) |
| | { |
| | return OGL_Renderer::GetNumDiffuseRenderParticles(buffers); |
| | } |
| |
|
| | void DemoContextOGL::beginLines() |
| | { |
| | OGL_Renderer::BeginLines(); |
| | } |
| |
|
| | void DemoContextOGL::drawLine(const Vec3& p, const Vec3& q, const Vec4& color) |
| | { |
| | OGL_Renderer::DrawLine(p, q, color); |
| | } |
| |
|
| | void DemoContextOGL::endLines() |
| | { |
| | OGL_Renderer::EndLines(); |
| | } |
| |
|
| | void DemoContextOGL::onSizeChanged(int width, int height, bool minimized) |
| | { |
| | OGL_Renderer::ReshapeRender(width, height, minimized); |
| | } |
| |
|
| | void DemoContextOGL::startGpuWork() |
| | { |
| | OGL_Renderer::StartGpuWork(); |
| | } |
| |
|
| | void DemoContextOGL::endGpuWork() |
| | { |
| | OGL_Renderer::EndGpuWork(); |
| | } |
| |
|
| | void DemoContextOGL::flushGraphicsAndWait() |
| | { |
| | } |
| |
|
| | void DemoContextOGL::setFillMode(bool wire) |
| | { |
| | OGL_Renderer::SetFillMode(wire); |
| | } |
| |
|
| | void DemoContextOGL::setCullMode(bool enabled) |
| | { |
| | OGL_Renderer::SetCullMode(enabled); |
| | } |
| |
|
| | void DemoContextOGL::drawImguiGraph() |
| | { |
| | OGL_Renderer::DrawImguiGraph(); |
| | } |
| |
|
| | void* DemoContextOGL::getGraphicsCommandQueue() |
| | { |
| | return OGL_Renderer::GetGraphicsCommandQueue(); |
| | } |
| |
|
| | void DemoContextOGL::getRenderDevice(void** device, void** context) |
| | { |
| | OGL_Renderer::GetRenderDevice(device, context); |
| | } |
| |
|
| |
|
| | |
| | void InitRenderHeadless(const RenderInitOptions& options, int width, int height) |
| | { |
| | #ifdef __linux__ |
| | int msaaSamples = options.numMsaaSamples; |
| |
|
| | EGLint ignore; |
| | EGLBoolean ok; |
| |
|
| | EGLNativeDisplayType native_display = EGL_DEFAULT_DISPLAY; |
| |
|
| | const char* s = getenv("EGL_GPU"); |
| | EGLDisplay selectedDisplay; |
| | if (s != NULL) |
| | { |
| | int egl_index = atoi(s); |
| | |
| | static const int MAX_DEVICES = 10; |
| | EGLDeviceEXT eglDevs[MAX_DEVICES]; |
| | EGLint numDevices; |
| |
|
| | PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT = |
| | (PFNEGLQUERYDEVICESEXTPROC) eglGetProcAddress("eglQueryDevicesEXT"); |
| |
|
| | eglQueryDevicesEXT(MAX_DEVICES, eglDevs, &numDevices); |
| |
|
| | printf("Detected %d devices\n", numDevices); |
| |
|
| | PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = |
| | (PFNEGLGETPLATFORMDISPLAYEXTPROC) eglGetProcAddress("eglGetPlatformDisplayEXT"); |
| |
|
| | selectedDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, eglDevs[egl_index], 0); |
| | } |
| | else |
| | { |
| | selectedDisplay = eglGetDisplay(native_display); |
| | } |
| |
|
| | EGLint eglSurfaceType = EGL_PBUFFER_BIT; |
| |
|
| |
|
| | EGLint eglConfigAttribs[] = { |
| | EGL_SURFACE_TYPE, eglSurfaceType, |
| | EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, |
| |
|
| | EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, |
| | EGL_BUFFER_SIZE, 32, |
| | EGL_RED_SIZE, 8, |
| | EGL_GREEN_SIZE, 8, |
| | EGL_BLUE_SIZE, 8, |
| | EGL_ALPHA_SIZE, 8, |
| |
|
| | EGL_DEPTH_SIZE, 24, |
| | EGL_STENCIL_SIZE, 8, |
| |
|
| | EGL_SAMPLE_BUFFERS, 0, |
| | EGL_SAMPLES, 0, |
| |
|
| | EGL_NONE, |
| | }; |
| |
|
| | static const EGLint eglPBAttribs[] = { |
| | EGL_WIDTH, width, |
| | EGL_HEIGHT, height, |
| | EGL_NONE, |
| | }; |
| |
|
| |
|
| | |
| | ok = eglBindAPI(EGL_OPENGL_API); |
| | if (!ok) |
| | printf("eglBindAPI(0x%x) failed", EGL_OPENGL_API); |
| |
|
| | |
| |
|
| | EGLDisplay g_eglDisplay = selectedDisplay; |
| | |
| | if (g_eglDisplay == EGL_NO_DISPLAY) |
| | printf("eglGetDisplay() failed"); |
| |
|
| | ok = eglInitialize(g_eglDisplay, &ignore, &ignore); |
| | if (!ok) |
| | printf("eglInitialize() failed"); |
| |
|
| | EGLint configs_size = 256; |
| | EGLConfig* configs = new EGLConfig[configs_size]; |
| | EGLint num_configs; |
| | ok = eglChooseConfig( |
| | g_eglDisplay, |
| | eglConfigAttribs, |
| | configs, |
| | configs_size, |
| | &num_configs); |
| |
|
| | if (!ok) |
| | printf("eglChooseConfig() failed"); |
| | if (num_configs == 0) |
| | printf("failed to find suitable EGLConfig"); |
| |
|
| | g_eglConfig = configs[0]; |
| | delete [] configs; |
| |
|
| | |
| | g_eglContext = eglCreateContext( |
| | g_eglDisplay, |
| | g_eglConfig, |
| | EGL_NO_CONTEXT, |
| | NULL); |
| | if (!g_eglContext) |
| | printf("eglCreateContext() failed"); |
| | |
| | g_eglSurface = eglCreatePbufferSurface(g_eglDisplay, g_eglConfig, |
| | eglPBAttribs); |
| | if (!g_eglSurface) |
| | printf("eglCreatePbufferSurface() failed"); |
| |
|
| |
|
| | |
| | ok = eglMakeCurrent(g_eglDisplay, g_eglSurface, g_eglSurface, g_eglContext); |
| | if (!ok) |
| | printf("eglMakeCurrent() failed"); |
| |
|
| | |
| | EGLint render_buffer; |
| | ok = eglQueryContext( |
| | g_eglDisplay, |
| | g_eglContext, |
| | EGL_RENDER_BUFFER, |
| | &render_buffer); |
| | if (!ok) |
| | printf("eglQueyContext(EGL_RENDER_BUFFER) failed"); |
| | if (render_buffer == EGL_SINGLE_BUFFER) |
| | printf("warn: EGL surface is single buffered\n"); |
| |
|
| |
|
| |
|
| |
|
| | |
| | if (!gladLoadEGL()) |
| | { |
| | printf("Could not initialize EGL extensions\n"); |
| | } |
| |
|
| | if (!gladLoadGL()) |
| | { |
| | printf("Could not initialize GL extensions\n"); |
| | } |
| |
|
| | g_msaaSamples = msaaSamples; |
| |
|
| |
|
| |
|
| |
|
| |
|
| | if (g_msaaSamples) |
| | { |
| | glVerify(glBindFramebuffer(GL_FRAMEBUFFER, 0)); |
| |
|
| | if (g_msaaFbo) |
| | { |
| | glVerify(glDeleteFramebuffers(1, &g_msaaFbo)); |
| | glVerify(glDeleteRenderbuffers(1, &g_msaaColorBuf)); |
| | glVerify(glDeleteRenderbuffers(1, &g_msaaDepthBuf)); |
| | } |
| |
|
| | int samples; |
| | glGetIntegerv(GL_MAX_SAMPLES_EXT, &samples); |
| |
|
| | |
| | |
| | samples = g_msaaSamples; |
| |
|
| | glVerify(glGenFramebuffers(1, &g_msaaFbo)); |
| | glVerify(glBindFramebuffer(GL_FRAMEBUFFER, g_msaaFbo)); |
| |
|
| | glVerify(glGenRenderbuffers(1, &g_msaaColorBuf)); |
| | glVerify(glBindRenderbuffer(GL_RENDERBUFFER, g_msaaColorBuf)); |
| | glVerify(glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGBA8, width, height)); |
| |
|
| | glVerify(glGenRenderbuffers(1, &g_msaaDepthBuf)); |
| | glVerify(glBindRenderbuffer(GL_RENDERBUFFER, g_msaaDepthBuf)); |
| | glVerify(glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT, width, height)); |
| | glVerify(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, g_msaaDepthBuf)); |
| |
|
| | glVerify(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, g_msaaColorBuf)); |
| |
|
| | glVerify(glCheckFramebufferStatus(GL_FRAMEBUFFER)); |
| |
|
| | glEnable(GL_MULTISAMPLE); |
| | } |
| |
|
| | g_screenWidth = width; |
| | g_screenHeight = height; |
| |
|
| | #endif |
| |
|
| | } |