Forum Discussion
mgarciacabe
13 years agoHonored Guest
OpenGL full example and shader...
Hello,
Great job with Rift and SDK. It seems awesome!. Waiting for my SDK...
A question:
- It's planned to release an new version of SDK with a minimal example (OculusRoomTiny) for OpenGL (with lens correction shader)?
- When? Soon? (to do this work myself or wait for new release)
Thanks!
Fernando
Great job with Rift and SDK. It seems awesome!. Waiting for my SDK...
A question:
- It's planned to release an new version of SDK with a minimal example (OculusRoomTiny) for OpenGL (with lens correction shader)?
- When? Soon? (to do this work myself or wait for new release)
Thanks!
Fernando
36 Replies
- JustinHonored GuestAww... your title got my hopes up. :cry: All I really want is the shader.
- CSHokieProtegeI assume that it is planned once OSX and Linux are supported. But until then, maybe somebody in the community will come up with something. I also prefer OGL to D3D...
- 38leinaDHonored GuestHave a check in the sources of the OculusRoomTiny Demo sources. The contained shaders are for Direct3D but should be easily transferable.
- JustinHonored Guest
"38leinaD" wrote:
Have a check in the sources of the OculusRoomTiny Demo sources. The contained shaders are for Direct3D but should be easily transferable.
Good idea! I don't know anything about D3D, but I'll see if I can figure it out. - cyberealityGrand ChampionI think an OpenGL example is something we would like to have in the future, but I don't have a clear time-table as to when it might be ready. If you want to integrate with OpenGL you can probably just pick the relevant pieces out of the Direct3D example, and porting the shader over should be straight-forward.
- JamesMcCraeExplorerIf nobody gets to it before me, when my dev kit arrives (hoping for April) I will definitely make a simple OpenGL/GLSL Rift app happen and put the code out there.
(Linux support for the Rift SDK has always been on my wish list, and plans are still to support it, which is great!) :D
EDIT: To make good on that word long ago:
http://www.dgp.toronto.edu/~mccrae/projects/firebox/ - ganzuulHonored GuestThis isn't OpenGL, but perhaps the next best thing which is three.js:
http://sxp.me/rift/rift.js
Not mine, just something that came up when goolging for rift+webgl. - densohaxExplorerHey I have the GLSL for you guys, but I modified it a bit to work with the way I render in Quake.
I render fullscreen stretched in width on color attachment 0 for left eye and color attachment 1 for right eye.
So I don't render side by side, you might have to adjust the shader accordingly.
uniform sampler2D texid;
uniform vec2 LensCenter;
uniform vec2 ScreenCenter;
uniform vec2 Scale;
uniform vec2 ScaleIn;
uniform vec4 HmdWarpParam;
void main()
{
vec2 uv = gl_TexCoord[0].xy;
vec2 theta = (uv - LensCenter) *ScaleIn;
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);
vec2 tc = (LensCenter + Scale * rvector);
//*** Adjust 0.5,0.5 according to how you render
if (any(bvec2(clamp(tc, ScreenCenter-vec2(0.50,0.5), ScreenCenter+vec2(0.50,0.5))-tc)))
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
else
gl_FragColor = texture2D(texid, tc);
} - mgarciacabeHonored GuestDensohax,
Thank you very much for the shader. I hope to have some free time to test it in a few days. I'll attach the final code and some screenshots...
Greetings,
Fer - 38leinaDHonored GuestYou where faster densohax :-)
Anywhere, here is my selfcontained example for the Barrel Distortion Shader. Sorry, I am little quicker with Java. Uses OpenGL via LWJGL.import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.*;
public class DistortionCorrection {
public enum Eye {
Left, Right
};
protected int shader=0;
protected int vertShader=0;
protected int fragShader=0;
protected int colorTextureID;
protected int framebufferID;
protected int depthRenderBufferID;
private int LensCenterLocation;
private int ScreenCenterLocation;
private int ScaleLocation;
private int ScaleInLocation;
private int HmdWarpParamLocation;
private final static String VERTEX_SHADER_SOURCE =
"void main() {\n" +
" gl_TexCoord[0] = gl_MultiTexCoord0;\n" +
" gl_Position = gl_Vertex;\n" +
"}";
private final static String FRAGMENT_SHADER_SOURCE =
"uniform sampler2D tex;\n" +
"uniform vec2 LensCenter;\n" +
"uniform vec2 ScreenCenter;\n" +
"uniform vec2 Scale;\n" +
"uniform vec2 ScaleIn;\n" +
"uniform vec4 HmdWarpParam;\n" +
"\n" +
"vec2 HmdWarp(vec2 texIn)\n" +
"{\n" +
" vec2 theta = (texIn - LensCenter) * ScaleIn;\n" +
" float rSq= theta.x * theta.x + theta.y * theta.y;\n" +
" vec2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + " +
" HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);\n" +
" return LensCenter + Scale * theta1;\n" +
"}\n" +
"\n" +
"\n" +
"\n" +
"void main()\n" +
"{\n" +
" vec2 tc = HmdWarp(gl_TexCoord[0]);\n" +
" if (any(notEqual(clamp(tc, ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25, 0.5)) - tc, vec2(0.0, 0.0))))\n" +
" gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\n" +
" else\n" +
" gl_FragColor = texture2D(tex, tc);\n" +
"}";
public DistortionCorrection(int screenWidth, int screenHeight) {
initShaders(VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE);
initFBO(screenWidth, screenHeight);
Util.checkGLError();
LensCenterLocation = glGetUniformLocation(shader, "LensCenter");
ScreenCenterLocation = glGetUniformLocation(shader, "ScreenCenter");
ScaleLocation = glGetUniformLocation(shader, "Scale");
ScaleInLocation = glGetUniformLocation(shader, "ScaleIn");
HmdWarpParamLocation = glGetUniformLocation(shader, "HmdWarpParam");
System.out.println(FRAGMENT_SHADER_SOURCE);
Util.checkGLError();
}
private void initFBO(int screenWidth, int screenHeight) {
framebufferID = glGenFramebuffers();
colorTextureID = glGenTextures();
depthRenderBufferID = glGenRenderbuffers();
glBindFramebuffer(GL_FRAMEBUFFER, framebufferID);
// initialize color texture
glBindTexture(GL_TEXTURE_2D, colorTextureID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, screenWidth, screenHeight, 0,GL_RGBA, GL_INT, (java.nio.ByteBuffer) null);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, colorTextureID, 0);
// initialize depth renderbuffer
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderBufferID);
glRenderbufferStorage(GL_RENDERBUFFER, GL14.GL_DEPTH_COMPONENT24, screenWidth, screenHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER, depthRenderBufferID);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
public void beginOffScreenRenderPass() {
glBindTexture(GL_TEXTURE_2D, 0);
Util.checkGLError();
glBindFramebuffer(GL_FRAMEBUFFER, framebufferID);
Util.checkGLError();
}
public void endOffScreenRenderPass() {
}
public void renderToScreen() {
Util.checkGLError();
glUseProgram(shader);
Util.checkGLError();
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClearColor (1.0f, 0.0f, 0.0f, 0.5f);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, colorTextureID);
renderDistortedEye(Eye.Left, 0.0f, 0.0f, 0.5f, 1.0f);
renderDistortedEye(Eye.Right, 0.5f, 0.0f, 0.5f, 1.0f);
glUseProgram(0);
glEnable(GL_DEPTH_TEST);
}
public static float K0 = 1.0f;
public static float K1 = 0.22f;
public static float K2 = 0.24f;
public static float K3 = 0.0f;
public void renderDistortedEye(Eye eye, float x, float y, float w, float h) {
float as = w/h;
float scaleFactor = 1.0f;
this.validate();
Util.checkGLError();
float DistortionXCenterOffset;
if (eye == Eye.Left) {
DistortionXCenterOffset = 0.25f;
}
else {
DistortionXCenterOffset = -0.25f;
}
glUniform2f(LensCenterLocation, x + (w + DistortionXCenterOffset * 0.5f)*0.5f, y + h*0.5f);
glUniform2f(ScreenCenterLocation, x + w*0.5f, y + h*0.5f);
glUniform2f(ScaleLocation, (w/2.0f) * scaleFactor, (h/2.0f) * scaleFactor * as);;
glUniform2f(ScaleInLocation, (2.0f/w), (2.0f/h) / as);
glUniform4f(HmdWarpParamLocation, K0, K1, K2, K3);
if (eye == Eye.Left) {
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
glTexCoord2f(0.5f, 0.0f); glVertex2f(0.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f);
glTexCoord2f(0.5f, 1.0f); glVertex2f(0.0f, 1.0f);
glEnd();
}
else {
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(0.5f, 0.0f); glVertex2f(0.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f, -1.0f);
glTexCoord2f(0.5f, 1.0f); glVertex2f(0.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f, 1.0f);
glEnd();
}
}
protected void initShaders(String vertexShader, String fragmentShader) {
shader=glCreateProgram();
vertShader=createVertShader(vertexShader);
fragShader=createFragShader(fragmentShader);
Util.checkGLError();
if (vertShader != 0 && fragShader != 0) {
glAttachShader(shader, vertShader);
glAttachShader(shader, fragShader);
glLinkProgram(shader);
if (glGetProgram(shader, GL_LINK_STATUS) == GL_FALSE) {
System.out.println("Linkage error");
printLogInfo(shader);
System.exit(0);
}
glValidateProgram(shader);
if (glGetProgram(shader, GL_VALIDATE_STATUS) == GL_FALSE) {
printLogInfo(shader);
System.exit(0);
}
} else {
System.out.println("No shaders");
System.exit(0);
}
Util.checkGLError();
}
public void validate() {
glValidateProgram(shader);
if (glGetProgram(shader, GL_VALIDATE_STATUS) == GL_FALSE) {
printLogInfo(shader);
}
}
private int createVertShader(String vertexCode){
vertShader=glCreateShader(GL_VERTEX_SHADER);
if (vertShader==0) {
return 0;
}
glShaderSource(vertShader, vertexCode);
glCompileShader(vertShader);
if (glGetShader(vertShader, GL_COMPILE_STATUS) == GL_FALSE) {
printLogInfo(vertShader);
vertShader=0;
}
return vertShader;
}
private int createFragShader(String fragCode){
fragShader = glCreateShader(GL_FRAGMENT_SHADER);
if (fragShader==0) {
return 0;
}
glShaderSource(fragShader, fragCode);
glCompileShader(fragShader);
if (glGetShader(fragShader, GL_COMPILE_STATUS) == GL_FALSE) {
printLogInfo(fragShader);
fragShader=0;
}
return fragShader;
}
protected static boolean printLogInfo(int obj){
IntBuffer iVal = BufferUtils.createIntBuffer(1);
glGetShader(obj,GL_INFO_LOG_LENGTH, iVal);
int length = iVal.get();
if (length > 1) {
ByteBuffer infoLog = BufferUtils.createByteBuffer(length);
iVal.flip();
glGetShaderInfoLog(obj, iVal, infoLog);
byte[] infoBytes = new byte[length];
infoLog.get(infoBytes);
String out = new String(infoBytes);
System.out.println("Info log:\n"+out);
return false;
}
else {
return true;
}
}
public static void main(String[] args) {
try {
DisplayMode displayMode = new DisplayMode(640, 400);
Display.setDisplayMode(displayMode);
Display.setTitle("Barrel Distorion Shader");
//Display.setLocation(-1000, 200);
PixelFormat pixelFormat = new PixelFormat(8, 8, 8);
Display.create(pixelFormat);
} catch (LWJGLException e) {
e.printStackTrace();
}
DistortionCorrection shader = new DistortionCorrection(640, 400);
while (!Display.isCloseRequested()) {
if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
System.exit(0);
}
shader.beginOffScreenRenderPass();
glDisable(GL_DEPTH_TEST);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_LINES);
glColor3f(1.0f, 0.0f, 0.0f);
for (int i=0; i<20; i++) {
glVertex2f(-1.0f, -1.0f + 0.1f * i);
glVertex2f(1.0f, -1.0f + 0.1f * i);
}
for (int i=0; i<20; i++) {
glVertex2f(-1.0f + 0.1f * i, -1.0f);
glVertex2f(-1.0f + 0.1f * i, 1.0f);
}
glEnd();
shader.endOffScreenRenderPass();
shader.renderToScreen();
Display.sync(60);
Display.update();
}
}
}
Quick Links
- Horizon Developer Support
- Quest User Forums
- Troubleshooting Forum for problems with a game or app
- Quest Support for problems with your device
Other Meta Support
Related Content
- 5 years ago
- 8 months ago