(OpenGL ShadowMap)Shadow cast on incorrect faces - opengl

Here is the demo image:
(Left top 256x256 rect is the depth texture)
I render the shadow map in the first pass(with parallel projection),
then render the scene in the second pass,
then render the scene with shadow map in the final pass.
the shadow is sometimes rendered twice or on the wrong surfaces
Is there any solution?
Full code here:
typedef struct
{
vec3_t org;//origin
vec3_t off;//position offset
vec3_t ang;//angle
float dist;//radius
int w;//default 512
int h;//default 512
int depth;//depth texture
int color;//color texture
int dimension;//default = 8
float mvmatrix[16];
float projmatrix[16];
cl_entity_t *followent;
int inuse;
}sdlight_t;
void R_RenderDepthMap()
{
qglPolygonOffset( 5.0, 0.0 );
qglEnable(GL_POLYGON_OFFSET_FILL);
if(cursdlight->followent)
{
VectorCopy(cursdlight->followent->origin, cursdlight->org);
}
qglMatrixMode(GL_PROJECTION);
qglLoadIdentity();
qglOrtho(-cursdlight->w / cursdlight->dimension, cursdlight->w / cursdlight->dimension, -cursdlight->h / cursdlight->dimension, cursdlight->h / cursdlight->dimension, -9999, 9999);//cursdlight->dist
qglMatrixMode(GL_MODELVIEW);
qglLoadIdentity();
qglRotatef(-90, 1, 0, 0);
qglRotatef(90, 0, 0, 1);
qglRotatef(-cursdlight->ang[2], 1, 0, 0);
qglRotatef(-cursdlight->ang[0], 0, 1, 0);
qglRotatef(-cursdlight->ang[1], 0, 0, 1);
qglTranslatef(-cursdlight->org[0], -cursdlight->org[1], -cursdlight->org[2]);
qglViewport(0, 0, cursdlight->w, cursdlight->h);
glGetFloatv(GL_PROJECTION_MATRIX, cursdlight->projmatrix);
glGetFloatv(GL_MODELVIEW_MATRIX, cursdlight->mvmatrix);
qglDepthRange(1.0, 0.0);
qglDepthFunc(GL_LEQUAL);
qglEnable(GL_CULL_FACE);
//qglCullFace(GL_FRONT);
qglClearColor(1, 1, 1, 1);
qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Render Models..
R_DrawEntitiesOnList();
qglDisable(GL_POLYGON_OFFSET_FILL);
qglBindFramebufferEXT(GL_READ_FRAMEBUFFER, s_BackBufferFBO.s_hBackBufferFBO);
qglActiveTextureARB(GL_TEXTURE0);
qglBindTexture(GL_TEXTURE_2D, cursdlight->depth);
qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 0, 0, cursdlight->w, cursdlight->h, 0);
}
void R_SetupShadowLight(void)
{
// enable automatic texture coordinates generation
GLfloat planeS[] = {1.0, 0.0, 0.0, 0.0};
GLfloat planeT[] = {0.0, 1.0, 0.0, 0.0};
GLfloat planeR[] = {0.0, 0.0, 1.0, 0.0};
GLfloat planeQ[] = {0.0, 0.0, 0.0, 1.0};
// setup texture stages
qglActiveTextureARB(GL_TEXTURE0_ARB);
qglBindTexture(GL_TEXTURE_2D, cursdlight->depth);
qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_REF_TO_TEXTURE);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
qglTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
qglEnable(GL_TEXTURE_GEN_S);
qglEnable(GL_TEXTURE_GEN_T);
qglEnable(GL_TEXTURE_GEN_R);
qglEnable(GL_TEXTURE_GEN_Q);
qglTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
qglTexGenfv(GL_S, GL_EYE_PLANE, planeS);
qglTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
qglTexGenfv(GL_T, GL_EYE_PLANE, planeT);
qglTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
qglTexGenfv(GL_R, GL_EYE_PLANE, planeR);
qglTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
qglTexGenfv(GL_Q, GL_EYE_PLANE, planeQ);
// load texture projection matrix
qglMatrixMode(GL_TEXTURE);
qglLoadIdentity();
qglTranslatef(0.5, 0.5, 0.5);
qglScalef(0.5, 0.5, 0.5);
qglMultMatrixf(cursdlight->projmatrix);
qglMultMatrixf(cursdlight->mvmatrix);
qglMatrixMode(GL_MODELVIEW);
if (gl_polyoffset->value)
{
qglEnable(GL_POLYGON_OFFSET_FILL);
qglPolygonOffset(-1, -gl_polyoffset->value);
}
qglDepthMask(GL_FALSE);
qglEnable(GL_BLEND);
qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
qglColor4f(1,1,1,1);
qglUseProgramObjectARB(shadow_program);
qglUniform1iARB(shadow_uniform.shadowmap, 0);
}
void R_FinishShadowLight(void)
{
qglUseProgramObjectARB(0);
if (gl_polyoffset->value)
{
qglDisable(GL_POLYGON_OFFSET_FILL);
}
qglDepthMask(GL_TRUE);
qglDisable(GL_BLEND);
qglActiveTextureARB(GL_TEXTURE0_ARB);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
qglMatrixMode(GL_TEXTURE);
qglLoadIdentity();
qglDisable(GL_TEXTURE_GEN_S);
qglDisable(GL_TEXTURE_GEN_T);
qglDisable(GL_TEXTURE_GEN_R);
qglDisable(GL_TEXTURE_GEN_Q);
qglMatrixMode(GL_MODELVIEW);
}
void R_DrawShadows(void)
{
for (int i = 0; i < numsdlights; i++)
{
cursdlight = &sdlights[i];
if(!R_ShouldCastShadow())
continue;
R_SetupShadowLight();
R_DrawSceneShadow();
R_FinishShadowLight();
}
}
GLSL part:
//vertex shader
varying vec4 shadowcoord;
void main()
{
shadowcoord = gl_TextureMatrix[0] * gl_Vertex;
gl_Position = ftransform();
}
//fragment shader
#version 120
uniform sampler2DShadow shadowmap;
varying vec4 shadowcoord;
uniform float xoffset = 1.0/512.0;
uniform float yoffset = 1.0/512.0;
float lookup(vec4 coord, vec2 offSet)
{
return shadow2DProj(shadowmap, coord + vec4(offSet.x * xoffset, offSet.y * yoffset, 0.0, 0.0) ).w;
}
void main()
{
float shadow;
shadow = lookup(shadowcoord, vec2(0.0,0.0)) + lookup(shadowcoord, vec2(0.035,0.0)) + lookup(shadowcoord, vec2(-0.035,0.0)) + lookup(shadowcoord, vec2(0.0,0.035)) + lookup(shadowcoord, vec2(0.0,-0.035));
shadow /= 5.0;
if(shadow == 1.0)
discard;
else
gl_FragColor = vec4(0.0, 0.0, 0.0, (1.0-shadow) * 0.5);
}

Related

GLSL: Geometry lacks depth

Using WebGL + GLSL, I'm trying to render a prism with the following vertex indices:
So far, though, I haven't been able to get this to render a prism -- I get instead a triangular plane:
var canvas,
gl,
fs,
vs,
glProgram,
vertexBuffer,
vertexIndexBuffer,
colorBuffer,
positionVal,
colorVal,
mvMatrix = mat4.create(),
pMatrix = mat4.create(),
angle = 0.01;
function initWebgl() {
canvas = document.querySelector('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
try {
gl = canvas.getContext('webgl')
gl.enable(gl.DEPTH_TEST)
gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT)
} catch(err) {
alert('Your browser does not support Webgl')
return;
}
// set the default background color
gl.clearColor(0.9, 0.9, 0.9, 1.0)
gl.clear(gl.COLOR_BUFFER_BIT)
}
function initCamera() {
// set camera area, fov, near clip, far clip, and translation
gl.viewport(0, 0, canvas.width, canvas.height)
mat4.perspective(45, canvas.width/canvas.height, 0.1, 100, pMatrix);
mat4.identity(mvMatrix);
mat4.translate(mvMatrix, [0, 0, -2.0]);
}
function initShaders() {
vs = buildShader('#shader-vs', gl.VERTEX_SHADER)
fs = buildShader('#shader-fs', gl.FRAGMENT_SHADER)
}
function buildShader(selector, type) {
var src = document.querySelector(selector).innerHTML;
var shader = gl.createShader(type)
gl.shaderSource(shader, src)
gl.compileShader(shader)
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.warn('Shader error', selector, gl.getShaderInfoLog(shader))
}
return shader;
}
function initProgram() {
glProgram = gl.createProgram()
gl.attachShader(glProgram, vs)
gl.attachShader(glProgram, fs)
gl.linkProgram(glProgram)
if (!gl.getProgramParameter(glProgram, gl.LINK_STATUS)) {
console.warn('Program link error')
}
gl.useProgram(glProgram)
}
function updatePositions() {
mat4.identity(mvMatrix)
mat4.translate(mvMatrix, [-1.0, -1.0, -7.0])
mat4.rotate(mvMatrix, angle, [0.0, 1.0, 0.0])
angle += 0.01;
}
function getBuffers() {
// vertex buffer
var vertexData = new Float32Array([
// front
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0,
0, 0.5, 0.0,
// back
-0.5, -0.5, 5,
0.5, -0.5, 5,
0, 0.5, 5,
])
vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData), gl.STATIC_DRAW)
// vertex index buffer - creates prism
var vertexIndices = new Uint16Array([
// front
0, 1, 2,
// right
1, 2, 4,
2, 4, 5,
// back
3, 4, 5,
// left
2, 3, 5,
0, 2, 3,
// bottom
0, 1, 3,
1, 3, 4,
])
vertexIndexBuffer = gl.createBuffer()
vertexIndexBuffer.number_vertex_points = vertexIndices.length;
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer)
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, vertexIndices, gl.STATIC_DRAW)
// color buffer
colorVal = colorVal || 0.5;
colorVal += 0.01;
var colorData = new Float32Array([
Math.sin(colorVal) + 1, Math.cos(colorVal) + 1, 1,
1, Math.sin(colorVal) + 1, 0,
Math.cos(colorVal) + 1, 1, 0,
Math.sin(colorVal) + 1, Math.cos(colorVal) + 1, 1,
1, Math.sin(colorVal) + 1, 0,
Math.cos(colorVal) + 1, 1, 0,
])
colorBuffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
gl.bufferData(gl.ARRAY_BUFFER, colorData, gl.DYNAMIC_DRAW)
}
function drawBuffers() {
// identify and bind vertex position attributes
var aVertexPosition = gl.getAttribLocation(glProgram, 'aVertexPosition')
gl.enableVertexAttribArray(aVertexPosition)
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer)
gl.vertexAttribPointer(aVertexPosition, 3, gl.FLOAT, false, 0.0, 0.0)
// identify and bind vertex color attributes
var aVertexColor = gl.getAttribLocation(glProgram, 'aVertexColor')
gl.enableVertexAttribArray(aVertexColor)
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
gl.vertexAttribPointer(aVertexColor, 3, gl.FLOAT, false, 0.0, 0.0)
// draw the data
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer)
gl.drawElements(gl.TRIANGLES, vertexIndexBuffer.number_vertex_points,
gl.UNSIGNED_SHORT, 0)
}
function getMatrixUniforms() {
glProgram.pMatrixUniform = gl.getUniformLocation(glProgram, 'uPMatrix')
glProgram.mvMatrixUniform = gl.getUniformLocation(glProgram, 'uMVMatrix')
}
function setMatrixUniforms() {
gl.uniformMatrix4fv(glProgram.pMatrixUniform, false, pMatrix)
gl.uniformMatrix4fv(glProgram.mvMatrixUniform, false, mvMatrix)
}
function render() {
updatePositions()
getBuffers()
drawBuffers()
setMatrixUniforms()
requestAnimationFrame(render, canvas)
}
initWebgl()
initCamera()
initShaders()
initProgram()
getMatrixUniforms()
render()
* {
margin: 0;
padding: 0;
}
body, html {
height: 100%;
width: 100%;
overflow: hidden;
background: skyblue;
}
<script src="https://rawgit.com/duhaime/955402641534b89babd41c8de8bc91f6/raw/5d86d54f7237f4cf2b206dcf0a3d453ba95acd1d/gl-matrix.js"></script>
<script id='shader-vs' type='x-shader/x-vertex'>
attribute vec3 aVertexPosition;
attribute vec3 aVertexColor;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
varying highp vec4 vColor;
void main() {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vColor = vec4(aVertexColor, 1.0);
}
</script>
<script id='shader-fs' type='x-shader/x-fragment'>
varying highp vec4 vColor;
void main() {
gl_FragColor = vColor;
}
</script>
<canvas />
Does anyone know what I can do to make the prism render? I'd be grateful for any pointers others can offer!
Whoops, I was passing the vertexIndexBuffer to the shaders to specify the positional attribute, but I should have passed the vertexBuffer to specify the positional attribute. This was the intended result:
var canvas,
gl,
fs,
vs,
glProgram,
vertexBuffer,
vertexIndexBuffer,
colorBuffer,
positionVal,
colorVal,
mvMatrix = mat4.create(),
pMatrix = mat4.create(),
angle = 0.01;
function initWebgl() {
canvas = document.querySelector('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
try {
gl = canvas.getContext('webgl')
gl.enable(gl.DEPTH_TEST)
gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT)
} catch(err) {
alert('Your browser does not support Webgl')
return;
}
// set the default background color
gl.clearColor(0.9, 0.9, 0.9, 1.0)
gl.clear(gl.COLOR_BUFFER_BIT)
}
function initCamera() {
// set camera area, fov, near clip, far clip, and translation
gl.viewport(0, 0, canvas.width, canvas.height)
mat4.perspective(45, canvas.width/canvas.height, 0.1, 100, pMatrix);
mat4.identity(mvMatrix);
mat4.translate(mvMatrix, [0, 0, -2.0]);
}
function initShaders() {
vs = buildShader('#shader-vs', gl.VERTEX_SHADER)
fs = buildShader('#shader-fs', gl.FRAGMENT_SHADER)
}
function buildShader(selector, type) {
var src = document.querySelector(selector).innerHTML;
var shader = gl.createShader(type)
gl.shaderSource(shader, src)
gl.compileShader(shader)
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.warn('Shader error', selector, gl.getShaderInfoLog(shader))
}
return shader;
}
function initProgram() {
glProgram = gl.createProgram()
gl.attachShader(glProgram, vs)
gl.attachShader(glProgram, fs)
gl.linkProgram(glProgram)
if (!gl.getProgramParameter(glProgram, gl.LINK_STATUS)) {
console.warn('Program link error')
}
gl.useProgram(glProgram)
}
function updatePositions() {
mat4.identity(mvMatrix)
mat4.translate(mvMatrix, [-1.0, -1.0, -7.0])
mat4.rotate(mvMatrix, angle, [0.0, 1.0, 0.0])
angle += 0.01;
}
function getBuffers() {
// vertex buffer
var vertexData = new Float32Array([
// front
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0,
0, 0.5, 0.0,
// back
-0.5, -0.5, 5,
0.5, -0.5, 5,
0, 0.5, 5,
])
vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData), gl.STATIC_DRAW)
// vertex index buffer - creates prism
var vertexIndices = new Uint16Array([
// front
0, 1, 2,
// right
1, 2, 4,
2, 4, 5,
// back
3, 4, 5,
// left
2, 3, 5,
0, 2, 3,
// bottom
0, 1, 3,
1, 3, 4,
])
vertexIndexBuffer = gl.createBuffer()
vertexIndexBuffer.number_vertex_points = vertexIndices.length;
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer)
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, vertexIndices, gl.STATIC_DRAW)
// color buffer
colorVal = colorVal || 0.5;
colorVal += 0.01;
var colorData = new Float32Array([
Math.sin(colorVal) + 1, Math.cos(colorVal) + 1, 1,
1, Math.sin(colorVal) + 1, 0,
Math.cos(colorVal) + 1, 1, 0,
Math.sin(colorVal) + 1, Math.cos(colorVal) + 1, 1,
1, Math.sin(colorVal) + 1, 0,
Math.cos(colorVal) + 1, 1, 0,
])
colorBuffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
gl.bufferData(gl.ARRAY_BUFFER, colorData, gl.DYNAMIC_DRAW)
}
function drawBuffers() {
// identify and bind vertex position attributes
var aVertexPosition = gl.getAttribLocation(glProgram, 'aVertexPosition')
gl.enableVertexAttribArray(aVertexPosition)
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)
gl.vertexAttribPointer(aVertexPosition, 3, gl.FLOAT, false, 0.0, 0.0)
// identify and bind vertex color attributes
var aVertexColor = gl.getAttribLocation(glProgram, 'aVertexColor')
gl.enableVertexAttribArray(aVertexColor)
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
gl.vertexAttribPointer(aVertexColor, 3, gl.FLOAT, false, 0.0, 0.0)
// draw the data
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer)
gl.drawElements(gl.TRIANGLES, vertexIndexBuffer.number_vertex_points,
gl.UNSIGNED_SHORT, 0)
}
function getMatrixUniforms() {
glProgram.pMatrixUniform = gl.getUniformLocation(glProgram, 'uPMatrix')
glProgram.mvMatrixUniform = gl.getUniformLocation(glProgram, 'uMVMatrix')
}
function setMatrixUniforms() {
gl.uniformMatrix4fv(glProgram.pMatrixUniform, false, pMatrix)
gl.uniformMatrix4fv(glProgram.mvMatrixUniform, false, mvMatrix)
}
function render() {
updatePositions()
getBuffers()
drawBuffers()
setMatrixUniforms()
requestAnimationFrame(render, canvas)
}
initWebgl()
initCamera()
initShaders()
initProgram()
getMatrixUniforms()
render()
* {
margin: 0;
padding: 0;
}
body, html {
height: 100%;
width: 100%;
overflow: hidden;
background: skyblue;
}
<script src="https://rawgit.com/duhaime/955402641534b89babd41c8de8bc91f6/raw/5d86d54f7237f4cf2b206dcf0a3d453ba95acd1d/gl-matrix.js"></script>
<script id='shader-vs' type='x-shader/x-vertex'>
attribute vec3 aVertexPosition;
attribute vec3 aVertexColor;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
varying highp vec4 vColor;
void main() {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vColor = vec4(aVertexColor, 1.0);
}
</script>
<script id='shader-fs' type='x-shader/x-fragment'>
varying highp vec4 vColor;
void main() {
gl_FragColor = vColor;
}
</script>
<canvas />

How to ripple on a sphere

I'm trying to implement a program that turns a cube into a sphere based on key presses, and ripples whenever it's clicked. I managed to implement the cube-to-sphere-and-back part, but I have completely no idea where to start on the rippling. I've looked at tons of sources online, I get the math, but I have no idea how to implement it on my vertex shader. Can anyone help me with my dilemma? Thank you!
Here's my cpp, vsh, and fsh: https://drive.google.com/file/d/0B4hkcF9foOTgbUozMjZmSHJhQWM/view?usp=sharing
I'm using GLSL, OpenGL 4.4.0
Here's my code for the vertex shader:
#version 120
attribute vec3 pos;
varying vec4 out_color;
uniform float t;
float PI = 3.14159265357;
int factor = 2; //for determining colors
int num_colors; // = factor * 3 (because RGB)
float currang = 0;
float angfac;
vec4 calculate( float a )
{
//this is just to calculate for the color
}
void main() {
num_colors = factor*3;
angfac = 2*PI/num_colors;
float ang = atan( pos.z, pos.x )+PI;
out_color = calculate(ang);
//rotation
mat3 rotateX = mat3(
vec3( 1, 0, 0),
vec3( 0, cos(t), sin(t)),
vec3( 0, -sin(t), cos(t))
);
mat3 rotateY = mat3(
vec3( cos(t), 0, -sin(t)),
vec3( 0, 1, 0),
vec3( sin(t), 0, cos(t))
);
mat3 rotateZ = mat3(
vec3( cos(t), sin(t), 0),
vec3(-sin(t), cos(t), 0),
vec3( 0, 0, cos(t))
);
gl_Position = gl_ModelViewProjectionMatrix * vec4((pos.xyz*rotateY*rotateX) , 1.0 );
}
and here's parts of my cpp file:
//usual include statements
using namespace std;
enum { ATTRIB_POS };
GLuint mainProgram = 0;
// I use this to indicate the position of the vertices
struct Vtx {
GLfloat x, y, z;
};
const GLfloat PI = 3.14159265357;
const int sideLength = 10;
const size_t nVertices = (sideLength*sideLength*sideLength)-((sideLength-2)*(sideLength-2)*(sideLength-2));
Vtx cube[nVertices];
Vtx sphere[nVertices];
Vtx diff[nVertices];
const double TIME_SPEED = 0.01;
int mI = 4*(sideLength-1);
const int sLCubed = sideLength*sideLength*sideLength;
int indices[nVertices*nVertices];
GLfloat originX = 0.0f; //offset
GLfloat originY = 0.0f; //offset
bool loadShaderSource(GLuint shader, const char *path) {...}
void checkShaderStatus(GLuint shader) {...}
bool initShader() {...}
//in this part of the code, I instantiate an array of indices to be used by glDrawElements()
void transform(int fac)
{
//move from cube to sphere and back by adding/subtracting values and updating cube[].xyz
//moveSpeed = diff[]/speedFac
//fac is to determine direction (going to sphere or going to cube; going to sphere is plus, going back to cube is minus)
for( int i = 0; i<nVertices; i++ )
{
cube[i].x += fac*diff[i].x;
cube[i].y += fac*diff[i].y;
cube[i].z += fac*diff[i].z;
}
}
void initCube() {...} //computation for the vertices of the cube depending on sideLength
void initSphere() {...} //computation for the vertices of the sphere based on the vertices of the cube
void toSphere() {...} //changes the values of the array of vertices of the cube to those of the sphere
void initDiff() {...} //computes for the difference of the values of the vertices of the sphere and the vertices of the cube for the slow transformation
int main() {
//error checking (GLEW, OpenGL versions, etc)
glfwSetWindowTitle("CS177 Final Project");
glfwEnable( GLFW_STICKY_KEYS );
glfwSwapInterval( 1 );
glClearColor(0,0,0,0);
if ( !initShader() ) {
return -1;
}
glEnableVertexAttribArray(ATTRIB_POS);
glVertexAttribPointer(ATTRIB_POS, 3, GL_FLOAT, GL_FALSE, sizeof(Vtx), cube);
initCube();
initIndices();
initSphere();
initDiff();
glUseProgram(mainProgram);
GLuint UNIF_T = glGetUniformLocation(mainProgram, "t");
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
float t = 0;
glUniform1f(UNIF_T, t);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glPointSize(2.0);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glfwOpenWindowHint(GLFW_FSAA_SAMPLES,16);
glEnable(GL_MULTISAMPLE);
do {
int width, height;
glfwGetWindowSize( &width, &height );
glViewport( 0, 0, width, height );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
t += TIME_SPEED;
glUniform1f(UNIF_T, t);
if (glfwGetKey(GLFW_KEY_DEL)) transform(-1);
if (glfwGetKey(GLFW_KEY_INSERT)) transform( 1 );
if (glfwGetKey(GLFW_KEY_HOME)) initCube();
if (glfwGetKey(GLFW_KEY_END)) toSphere();
glDrawElements( GL_TRIANGLES, nVertices*nVertices, GL_UNSIGNED_INT, indices);
glfwSwapBuffers();
} while ( glfwGetKey(GLFW_KEY_ESC) != GLFW_PRESS &&
glfwGetWindowParam(GLFW_OPENED) );
glDeleteProgram(mainProgram);
glfwTerminate();
return 0;
}

Perspective-correct - Trapezoid - 2D - OpenGL GLSL

I am drawing a textured trapezoid in OpenGL and affine problem occurs:
http://upload.wikimedia.org/wikipedia/commons/5/57/Perspective_correct_texture_mapping.jpg
I want my texture this in perspective-correct.
I have to interpolate in the image space (sw tw w) and I don't know how to do it:
http://i.stack.imgur.com/O0AnC.png
I paste my current code project:
c++:
ttps://gist.github.com/danicomas/a1f5a0e6849b3ac8b51c169c2c030e37 (Add http)
vertex:
ttps://gist.github.com/danicomas/fee77cf48fc5085f61a2fcf7a2c6d5de (Add http)
fragment:
ttps://gist.github.com/danicomas/0bbd679d2d7da18bc61ee23b36096a16 (Add http)
How can I do this? Some example code?
Finally. I found it a simple solution!
c++
glPushMatrix();
glBegin(GL_QUADS);
float scale_texcoord = 0.7;
float top = 0.7;
float tx = scale_texcoord * top;
glTexCoord2f(-1 / 2, -1);
glVertex2f(-1.4, -1);
glTexCoord4f(0, 0, 0, tx);
glVertex2f(-top, 1);
glTexCoord4f( tx, 0, 0, tx);
glVertex2f( top, 1);
glTexCoord2f( 1, -1);
glVertex2f( 1.4, -1);
glEnd();
glPopMatrix();
fragment:
uniform sampler2D sampler;
void main()
{
vec2 interpolated = vec2(gl_TexCoord[0].x / gl_TexCoord[0].w, gl_TexCoord[0].y);
gl_FragColor = texture2D(sampler, vec2(interpolated.x, interpolated.y));
}

Rotation of my cube based on arcball quaternion rotation matrix slightly off

Im trying to rotate my cube using quaternion to matrix rotation based on arcball mouse movement. My cube is rendering, and it has movement/rotation, but it isnt simply just rotating around an axis, it is also moving in the direction of my mouse, so i think that either the data that im getting from my trackball is a bit off, or the way im transforming my quaternion into a rotation matrix is slightly off. trackball_ptov is where i translate mouse location to an arcball. mouseMotion() is where im creating the rotation matrix from the quaternion.
The entirety of my main:
#include "Angel.h"
#include <gl/glew.h>
#include <glut.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
using namespace std;
#define bool int /* if system does not support bool type */
#define false 0
#define true 1
#define M_PI 3.14159265358 /* if not in math.h */
int winWidth, winHeight;
float angle = 0.0, axis[3], trans[3];
bool trackingMouse = false;
float lastPos[3] = {0.0, 0.0, 0.0};
float aspect = 1.0;
int curx, cury;
int startX, startY;
int modelInit=1;
//the program object
GLuint program = 0;
glm::mat4 model;
typedef Angel::vec4 color4;
typedef Angel::vec4 point4;
const int NumVertices = 36; //(6 faces)(2 triangles/face)(3 vertices/triangle)
point4 points[NumVertices];
color4 colors[NumVertices];
enum { Xaxis = 0, Yaxis = 1, Zaxis = 2, NumAxes = 3 };
int Axis = Xaxis;
GLuint mvpUniform;
GLuint shaderaxis;
int Index = 0;
// Vertices of a unit cube centered at origin, sides aligned with axes
point4 vertices[8]={
point4(-0.5, -0.5, 0.5, 1.0),
point4(-0.5, 0.5, 0.5, 1.0),
point4(0.5, 0.5, 0.5, 1.0),
point4(0.5, -0.5, 0.5, 1.0),
point4(-0.5, -0.5, -0.5, 1.0),
point4(-0.5, 0.5, -0.5, 1.0),
point4(0.5, 0.5, -0.5, 1.0),
point4(0.5, -0.5, -0.5, 1.0)
};
// RGBA colors
color4 vertex_colors[8] = {
color4(0.0, 0.0, 0.0, 1.0), // black
color4(1.0, 0.0, 0.0, 1.0), // red
color4(1.0, 1.0, 0.0, 1.0), // yellow
color4(0.0, 1.0, 0.0, 1.0), // green
color4(0.0, 0.0, 1.0, 1.0), // blue
color4(1.0, 0.0, 1.0, 1.0), // magenta
color4(1.0, 1.0, 1.0, 1.0), // white
color4(0.0, 1.0, 1.0, 1.0) // cyan
};
// quad generates two triangles for each face and assigns colors to the vertices
void quad(int a, int b, int c, int d) {
colors[Index] = vertex_colors[a]; points[Index] = vertices[a]; Index++;
colors[Index] = vertex_colors[b]; points[Index] = vertices[b]; Index++;
colors[Index] = vertex_colors[c]; points[Index] = vertices[c]; Index++;
colors[Index] = vertex_colors[a]; points[Index] = vertices[a]; Index++;
colors[Index] = vertex_colors[c]; points[Index] = vertices[c]; Index++;
colors[Index] = vertex_colors[d]; points[Index] = vertices[d]; Index++;
}
// generate 12 triangles: 36 vertices and 36 colors
void colorcube(void) {
quad(1, 0, 3, 2);
quad(2, 3, 7, 6);
quad(3, 0, 4, 7);
quad(6, 5, 1, 2);
quad(4, 5, 6, 7);
quad(5, 4, 0, 1);
}
// OpenGL initialization
void init(void) {
colorcube();
// Load shaders and use the resulting shader program
GLuint program = InitShader("vshader36.glsl", "fshader36.glsl");
glUseProgram(program);
// Create a vertex array object
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Create and initialize a buffer object
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(points) + sizeof(colors), NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(points), points);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(points), sizeof(colors), colors);
// set up vertex arrays
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
model = glm::translate(glm::mat4(1.0), glm::vec3(0.0, 0.0, -5.0));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(points)));
mvpUniform = glGetUniformLocation(program, "mvp");
glEnable(GL_DEPTH_TEST);
glClearColor(1.0, 1.0, 1.0, 1.0);
}
void trackball_ptov(int x, int y, int width, int height, float v[3]) {
float d, a;
/* project x, y onto a hemisphere centered within width, height , note z is up here*/
v[0] = (2.0*x - width) / width;
v[1] = (height - 2.0F*y) / height;
d = sqrt(v[0]*v[0] + v[1]*v[1]);
v[2] = cos((M_PI/2.0) * ((d < 1.0) ? d : 1.0));
a = 1.0 / sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
v[0] *= a;
v[1] *= a;
v[2] *= a;
}
void display() {
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glm::mat4 proj = glm::perspective(90.F, 1.F, 0.1F, 100.F);
glm::mat4 view = glm::translate(glm::mat4(1.0), glm::vec3(0.0, 0.0, 0.0)); //apply mouse translation
//view = glm::rotate(view, 0.2*mousediff.x, glm::vec3(0.0, 1.0, 0.0)); //apply mouse rotation
//view = glm::rotate(view, 0.2*mousediff.y, glm::vec3(1.0, 0.0, 0.0));
//model = glm::translate(glm::mat4(1.0), glm::vec3(0.0, 0.0, -5.0));
//glUniformMatrix4fv(mvpUniform, 1, false, glm::value_ptr(proj));
glUniformMatrix4fv(mvpUniform, 1, false, glm::value_ptr(proj*view*model));
//glUniformMatrix4fv(mvpUniform, 1, false, glm::value_ptr(model*view*proj));
glDrawArrays(GL_TRIANGLES, 0, NumVertices);
glutSwapBuffers();
}
void keyboard(unsigned char key, int x, int y) {
switch(key) {
case 033: // Escape Key
case 'q': case 'Q':
exit(EXIT_SUCCESS);
break;
}
}
void mouseButton(int button, int state, int x, int y) {
if(button==GLUT_RIGHT_BUTTON) exit(0);
/* holding down left button allows user to rotate cube */
if(button==GLUT_LEFT_BUTTON)
switch(state) {
case GLUT_DOWN:
trackingMouse = true;
startX = x;
startY = y;
curx = x;
cury = y;
trackball_ptov(x, y, 512, 512, lastPos);
break;
case GLUT_UP:
trackingMouse = false;
angle = 0.0;
break;
}
}
void mouseMotion(int x, int y) {
float curPos[3], dx, dy, dz;
/* compute position on hemisphere */
if(trackingMouse) {
/* compute the change in position on the hemisphere */
trackball_ptov(x, y, 512, 512, curPos);
dx = curPos[0] - lastPos[0];
dy = curPos[1] - lastPos[1];
dz = curPos[2] - lastPos[2];
if (dx || dy || dz) {
/* compute theta and cross product */
angle = 90.0 * sqrt(dx*dx + dy*dy + dz*dz);
axis[0] = lastPos[1]*curPos[2] - lastPos[2]*curPos[1];
axis[1] = lastPos[2]*curPos[0] - lastPos[0]*curPos[2];
axis[2] = lastPos[0]*curPos[1] - lastPos[1]*curPos[0];
/* update position */
lastPos[0] = curPos[0];
lastPos[1] = curPos[1];
lastPos[2] = curPos[2];
}
float w = angle;
float x = axis[0];
float y = axis[1];
float z = axis[2];
glm::mat4 xform = glm::mat4((1.F - (2.F * ( y*y + z*z ))),(2.F * ( x*y - z*w )),( x*z + y*w ),0.F,
(2.F * ( x*y + z*w )),(1.F - (2.F * ( x*x + z*z ))),(2.F * ( y*z - x*w )),0.F,
(2.F * ( x*z - y*w )),(2.F * ( y*z + x*w )),(1.F - (2.F * ( x*x + y*y ))),0.F,
0.F,0.F,0.F,1.F);
model = xform*model;
}
glutPostRedisplay();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(512, 512);
glutCreateWindow("Color Cube");
glewInit();
init();
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutIdleFunc(display);
glutMouseFunc(mouseButton);
glutMotionFunc(mouseMotion);
glutMainLoop();
return 0;
}
Here is the fshader36
#version 150
in vec4 color;
out vec4 fColor;
void main()
{
fColor = color;
}
here is VSHADER
#version 330
uniform mat4 mvp;
layout(location=0) in vec4 vPosition;
layout(location=1) in vec4 vColor;
out vec4 color;
void main() {
color = vColor;
gl_Position = mvp * vPosition;
}

OpenGL Spotlights

I'm trying to make 'spotlights' over a pool table in openGL. This should be fairly simple, but something is going wrong, and I can't work out what.
I have a class 'PoolLight' that I'm using as a sort of holding class for the lights. Here is is:
#include "PoolLight.h"
#include "Glut/glut.h"
#include "GL/gl.h"
#include "GL/glu.h"
PoolLight::PoolLight() {
}
PoolLight::PoolLight(GLenum lightNumber, GLenum lightType, float red, float green, float blue, bool distant, float posX, float posY, float posZ)
{
this->lightNumber = lightNumber;
this->lightType = lightType;
color[0] = red; color[1] = green; color[2] = blue; color[3] = 1;
position[0] = posX; position[1] = posY; position[2] = posZ; position[3] = (int) (!distant);
glLightfv(lightNumber, lightType, color);
glLightfv(lightNumber, GL_POSITION, position);
enabled(true);
}
PoolLight::~PoolLight(void)
{
}
void PoolLight::setSpotlight(float angle, float attenuation, float dirX, float dirY, float dirZ) {
glLightf(lightNumber, GL_SPOT_EXPONENT, angle);
glLightf(lightNumber, GL_CONSTANT_ATTENUATION, attenuation);
glLightf(lightNumber, GL_LINEAR_ATTENUATION, 0.0f);
glLightf(lightNumber, GL_QUADRATIC_ATTENUATION, 0.0f);
spotDirection[0] = dirX; spotDirection[1] = dirY; spotDirection[2] = dirZ;
glLightfv(lightNumber, GL_SPOT_DIRECTION, spotDirection);
glLightf(lightNumber, GL_SPOT_CUTOFF, 60);
}
void PoolLight::enabled(bool enabled) {
if (enabled) glEnable(lightNumber);
else glDisable(lightNumber);
}
void PoolLight::reposition() {
glLightfv(lightNumber, GL_POSITION, position);
}
And in Display::Init, I have this code:
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glPointSize(6);
//Lighting
middleSpotlight = PoolLight(GL_LIGHT0, GL_DIFFUSE, .3, .3, 0.15, false, 0, 0, 50);
middleSpotlight.setSpotlight(60, 1, 0, 0, -1);
upperSpotlight = PoolLight(GL_LIGHT1, GL_DIFFUSE, .3, .3, 0.15, false, 0, 45, 50);
upperSpotlight.setSpotlight(60, 1, 0, 0, -1);
lowerSpotlight = PoolLight(GL_LIGHT2, GL_DIFFUSE, .3, .3, 0.15, false, 0, -45, 50);
lowerSpotlight.setSpotlight(60, 1, 0, 0, -1);
However, even when disabling all but the middle spotlight my scene is uniformly lit with a sort of 'blanket' lighting.
I feel like I'm probably missing something obvious, but I just can't see what.
This is due to how OpenGL default fixed function pipeline implements lighting: Lighting is evaluated only at the vertices, the resulting colour interpolated over the surface. If your whole table consists of just one large quad, exactly this happens.
Solution 1: Subdivide the mesh to a high degree.
Solution 2: Replace fixed function lighting with a per-fragment-illumination shader.