Browse Source

Added distortion shader to render

pull/129/merge
raysan5 8 years ago
parent
commit
b79ede4edb
3 changed files with 236 additions and 44 deletions
  1. +26
    -0
      examples/oculus_glfw_sample/base.vs
  2. +64
    -0
      examples/oculus_glfw_sample/distortion.fs
  3. +146
    -44
      examples/oculus_glfw_sample/rlgl_standalone_stereo.c

+ 26
- 0
examples/oculus_glfw_sample/base.vs View File

@ -0,0 +1,26 @@
#version 330
// Input vertex attributes
in vec3 vertexPosition;
in vec2 vertexTexCoord;
in vec3 vertexNormal;
in vec4 vertexColor;
// Input uniform values
uniform mat4 mvpMatrix;
// Output vertex attributes (to fragment shader)
out vec2 fragTexCoord;
out vec4 fragColor;
// NOTE: Add here your custom variables
void main()
{
// Send vertex attributes to fragment shader
fragTexCoord = vertexTexCoord;
fragColor = vertexColor;
// Calculate final vertex position
gl_Position = mvpMatrix*vec4(vertexPosition, 1.0);
}

+ 64
- 0
examples/oculus_glfw_sample/distortion.fs View File

@ -0,0 +1,64 @@
#version 330
// Input vertex attributes (from vertex shader)
in vec2 fragTexCoord;
// Input uniform values
uniform sampler2D texture0;
// Output fragment color
out vec4 finalColor;
// NOTE: Add here your custom variables
const vec2 LeftLensCenter = vec2(0.2863248, 0.5);
const vec2 RightLensCenter = vec2(0.7136753, 0.5);
const vec2 LeftScreenCenter = vec2(0.25, 0.5);
const vec2 RightScreenCenter = vec2(0.75, 0.5);
const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845);
const vec2 ScaleIn = vec2(4, 2.2222);
const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0);
/*
// Another set of default values
ChromaAbCorrection = {1.0, 0.0, 1.0, 0}
DistortionK = {1.0, 0.22, 0.24, 0}
Scale = {0.25, 0.5*AspectRatio, 0, 0}
ScaleIn = {4.0, 2/AspectRatio, 0, 0}
Left Screen Center = {0.25, 0.5, 0, 0}
Left Lens Center = {0.287994117, 0.5, 0, 0}
Right Screen Center = {0.75, 0.5, 0, 0}
Right Lens Center = {0.712005913, 0.5, 0, 0}
*/
// Scales input texture coordinates for distortion.
vec2 HmdWarp(vec2 in01, vec2 LensCenter)
{
vec2 theta = (in01 - LensCenter) * ScaleIn; // Scales to [-1, 1]
float rSq = theta.x * theta.x + theta.y * theta.y;
vec2 rvector = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);
return LensCenter + Scale * rvector;
}
void main()
{
// SOURCE: http://www.mtbs3d.com/phpbb/viewtopic.php?f=140&t=17081
// The following two variables need to be set per eye
vec2 LensCenter = gl_FragCoord.x < 540 ? LeftLensCenter : RightLensCenter;
vec2 ScreenCenter = gl_FragCoord.x < 540 ? LeftScreenCenter : RightScreenCenter;
//vec2 oTexCoord = (gl_FragCoord.xy + vec2(0.5, 0.5)) / vec2(1280, 800); //Uncomment if using BGE's built-in stereo rendering
vec2 tc = HmdWarp(fragTexCoord, LensCenter);
if (any(bvec2(clamp(tc,ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tc)))
{
gl_FragColor = vec4(vec3(0.0), 1.0);
}
else
{
//tc.x = gl_FragCoord.x < 640 ? (2.0 * tc.x) : (2.0 * (tc.x - 0.5)); //Uncomment if using BGE's built-in stereo rendering
gl_FragColor = texture2D(texture0, tc);
}
}

+ 146
- 44
examples/oculus_glfw_sample/rlgl_standalone_stereo.c View File

@ -24,11 +24,26 @@
#define RLGL_STANDALONE
#include "rlgl.h" // rlgl library: OpenGL 1.1 immediate-mode style coding
#include <stdlib.h> // Required for: abs()
#define RED (Color){ 230, 41, 55, 255 } // Red
#define MAROON (Color){ 190, 33, 55, 255 } // Maroon
#define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo)
#define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray
#define WHITE (Color){ 255, 255, 255, 255 } // White
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
// Rectangle type
typedef struct Rectangle {
int x;
int y;
int width;
int height;
} Rectangle;
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
@ -41,6 +56,8 @@ static void DrawGrid(int slices, float spacing);
static void DrawCube(Vector3 position, float width, float height, float length, Color color);
static void DrawCubeWires(Vector3 position, float width, float height, float length, Color color);
static void DrawRectangleV(Vector2 position, Vector2 size, Color color);
static void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint);
static void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint);
//----------------------------------------------------------------------------------
// Main Entry point
@ -52,7 +69,6 @@ int main(void)
const int screenWidth = 1080;
const int screenHeight = 600;
// GLFW3 Initialization + OpenGL 3.3 Context + Extensions
//--------------------------------------------------------
glfwSetErrorCallback(ErrorCallback);
@ -100,6 +116,14 @@ int main(void)
rlClearColor(245, 245, 245, 255); // Define clear color
rlEnableDepthTest(); // Enable DEPTH_TEST for 3D
Shader distortion = LoadShader("base.vs", "distortion.fs");
// TODO: Upload to distortion shader configuration parameters (screen size, etc.)
//SetShaderValue(Shader shader, int uniformLoc, float *value, int size);
// Create a RenderTexture2D to be used for render to texture
RenderTexture2D target = rlglLoadRenderTexture(screenWidth, screenHeight);
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
Camera camera;
@ -119,51 +143,75 @@ int main(void)
// Draw
//----------------------------------------------------------------------------------
rlEnableRenderTexture(target.id); // Enable render target
rlClearScreenBuffers(); // Clear current framebuffer
for (int i = 0; i < 2; i++)
{
rlViewport(i*screenWidth/2, 0, screenWidth/2, screenHeight);
// Calculate projection matrix (from perspective) and view matrix from camera look at
// TODO: Consider every eye fovy
Matrix matProj = MatrixPerspective(camera.fovy, (double)(screenWidth/2)/(double)screenHeight, 0.01, 1000.0);
MatrixTranspose(&matProj);
// TODO: Recalculate view matrix considering IPD (inter-pupillary-distance)
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
SetMatrixModelview(matView); // Replace internal modelview matrix by a custom one
SetMatrixProjection(matProj); // Replace internal projection matrix by a custom one
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, RAYWHITE);
DrawGrid(10, 1.0f);
// NOTE: Internal buffers drawing (3D data)
rlglDraw();
// Draw '2D' elements in the scene (GUI)
#define RLGL_CREATE_MATRIX_MANUALLY
#if defined(RLGL_CREATE_MATRIX_MANUALLY)
matProj = MatrixOrtho(0.0, screenWidth/2, screenHeight, 0.0, 0.0, 1.0);
MatrixTranspose(&matProj);
matView = MatrixIdentity();
SetMatrixModelview(matView); // Replace internal modelview matrix by a custom one
SetMatrixProjection(matProj); // Replace internal projection matrix by a custom one
#else // Let rlgl generate and multiply matrix internally
rlMatrixMode(RL_PROJECTION); // Enable internal projection matrix
rlLoadIdentity(); // Reset internal projection matrix
rlOrtho(0.0, screenWidth, screenHeight, 0.0, 0.0, 1.0); // Recalculate internal projection matrix
rlMatrixMode(RL_MODELVIEW); // Enable internal modelview matrix
rlLoadIdentity(); // Reset internal modelview matrix
#endif
// TODO: 2D not drawing properly on stereo rendering
//DrawRectangleV((Vector2){ 10.0f, 10.0f }, (Vector2){ 500.0f, 20.0f }, DARKGRAY);
// NOTE: Internal buffers drawing (2D data)
rlglDraw();
}
for (int i = 0; i < 2; i++)
{
rlViewport(i*screenWidth/2, 0, screenWidth/2, screenHeight);
rlDisableRenderTexture(); // Disable render target
// Set viewport to default framebuffer size (screen size)
rlViewport(0, 0, screenWidth, screenHeight);
// Calculate projection matrix (from perspective) and view matrix from camera look at
Matrix matProj = MatrixPerspective(camera.fovy, (double)(screenWidth/2)/(double)screenHeight, 0.01, 1000.0);
MatrixTranspose(&matProj);
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
SetMatrixModelview(matView); // Replace internal modelview matrix by a custom one
SetMatrixProjection(matProj); // Replace internal projection matrix by a custom one
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, RAYWHITE);
DrawGrid(10, 1.0f);
// NOTE: Internal buffers drawing (3D data)
rlglDraw();
// Draw '2D' elements in the scene (GUI)
#define RLGL_CREATE_MATRIX_MANUALLY
#if defined(RLGL_CREATE_MATRIX_MANUALLY)
matProj = MatrixOrtho(0.0, screenWidth/2, screenHeight, 0.0, 0.0, 1.0);
MatrixTranspose(&matProj);
matView = MatrixIdentity();
SetMatrixModelview(matView); // Replace internal modelview matrix by a custom one
SetMatrixProjection(matProj); // Replace internal projection matrix by a custom one
#else // Let rlgl generate and multiply matrix internally
rlMatrixMode(RL_PROJECTION); // Enable internal projection matrix
rlLoadIdentity(); // Reset internal projection matrix
rlOrtho(0.0, screenWidth, screenHeight, 0.0, 0.0, 1.0); // Recalculate internal projection matrix
rlMatrixMode(RL_MODELVIEW); // Enable internal modelview matrix
rlLoadIdentity(); // Reset internal modelview matrix
#endif
DrawRectangleV((Vector2){ 10.0f, 10.0f }, (Vector2){ 600.0f, 20.0f }, DARKGRAY);
// NOTE: Internal buffers drawing (2D data)
rlglDraw();
}
// Let rlgl reconfigure internal matrices using OpenGL 1.1 style coding
rlMatrixMode(RL_PROJECTION); // Enable internal projection matrix
rlLoadIdentity(); // Reset internal projection matrix
rlOrtho(0.0, screenWidth, screenHeight, 0.0, 0.0, 1.0); // Recalculate internal projection matrix
rlMatrixMode(RL_MODELVIEW); // Enable internal modelview matrix
rlLoadIdentity(); // Reset internal modelview matrix
// Draw RenderTexture (fbo) using distortion shader
BeginShaderMode(distortion);
// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0, 0 }, WHITE);
EndShaderMode();
glfwSwapBuffers(window);
glfwPollEvents();
@ -172,7 +220,9 @@ int main(void)
// De-Initialization
//--------------------------------------------------------------------------------------
rlglClose(); // Unload rlgl internal buffers and default shader/texture
UnloadShader(distortion);
rlglClose(); // Unload rlgl internal buffers and default shader/texture
glfwDestroyWindow(window);
glfwTerminate();
@ -392,3 +442,55 @@ void DrawCubeWires(Vector3 position, float width, float height, float length, Co
rlEnd();
rlPopMatrix();
}
// Draw a part of a texture (defined by a rectangle)
static void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint)
{
Rectangle destRec = { (int)position.x, (int)position.y, abs(sourceRec.width), abs(sourceRec.height) };
Vector2 origin = { 0, 0 };
DrawTexturePro(texture, sourceRec, destRec, origin, 0.0f, tint);
}
// Draw a part of a texture (defined by a rectangle) with 'pro' parameters
// NOTE: origin is relative to destination rectangle size
static void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint)
{
// Check if texture is valid
if (texture.id != 0)
{
if (sourceRec.width < 0) sourceRec.x -= sourceRec.width;
if (sourceRec.height < 0) sourceRec.y -= sourceRec.height;
rlEnableTexture(texture.id);
rlPushMatrix();
rlTranslatef(destRec.x, destRec.y, 0);
rlRotatef(rotation, 0, 0, 1);
rlTranslatef(-origin.x, -origin.y, 0);
rlBegin(RL_QUADS);
rlColor4ub(tint.r, tint.g, tint.b, tint.a);
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
// Bottom-left corner for texture and quad
rlTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height);
rlVertex2f(0.0f, 0.0f);
// Bottom-right corner for texture and quad
rlTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
rlVertex2f(0.0f, destRec.height);
// Top-right corner for texture and quad
rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
rlVertex2f(destRec.width, destRec.height);
// Top-left corner for texture and quad
rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height);
rlVertex2f(destRec.width, 0.0f);
rlEnd();
rlPopMatrix();
rlDisableTexture();
}
}

Loading…
Cancel
Save