OpenGL - Grid not connected - c++

My code for creating my grid is:
// Per-vertex position vectors
static float planeVertices[16] =
{
0,1,0,1,
0,0,0,1,
1,1,0,1,
1,0,0,1
};
// 12 faces each with 3 vertices (each face forms a triangle) (36 indices total)
static unsigned short planeVertexIndices[4] =
{
0,1,2,3
};
drawPlane:
void drawPlane(float x, float y, float z){
glUseProgram(planeShader);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// Setup simple translation (model) matrix and pass to shader
GUMatrix4 planeModelTransform = GUMatrix4::translationMatrix(x, y, z);
static GLint planeShader_modelMatrixLocation = glGetUniformLocation(planeShader, "modelMatrix");
glUniformMatrix4fv(planeShader_modelMatrixLocation, 1, GL_FALSE, (const GLfloat*)&planeModelTransform);
glBindVertexArray(planeVAO);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (const GLvoid*)1);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
//glBindVertexArray(0);
}
How its drawn in update:
int gridSize = 100;
float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
for (float x = -gridSize/2; x < gridSize/2; x++){
for (float y = -gridSize/2; y < gridSize/2; y++){
drawPlane(x, y, z);
}
}
The grid draws fine, but none of its connected as I want the grid to wave, when I make it wave you can see the triangles are all separate.
My vertex shader:
#version 330
uniform float waveTime;
uniform float waveWidth;
uniform float waveHeight;
// UBO to store the camera projection and view matrices
uniform CameraMatrixBlock {
mat4 viewMatrix;
mat4 projectionMatrix;
} cam;
uniform mat4 modelMatrix;
layout (location=0) in vec4 vertexPos;
layout (location=1) in vec4 vertexColour;
out vec4 vp;
out vec4 colour;
void main(void) {
colour = vertexColour;
vec4 vp = vertexPos;
mat4 P = cam.projectionMatrix;
mat4 V = cam.viewMatrix;
mat4 mvpMatrix = P * V * modelMatrix;
vp.z = sin(waveWidth * vp.x + waveTime) * cos(waveWidth * vp.y + waveTime) * waveHeight;
gl_Position = mvpMatrix * vp;
}
What the result I get from all this:
The results

Related

Seam on Checkerboard Sphere UV Mapping

When I create a checkerboard texture on a sphere using UV mapping, I get a seam. I know there are a couple question about this, but I haven't found an answer involving a .frag file.
Here is the UV transformation in my main.cpp file:
void Update_Uv_Using_Spherical_Coordinates(const std::vector<Vector3>& vertices,std::vector<Vector2>& uv)
{
uv.clear();
/*Your implementation starts*/
Vector3 center = Vector3(0., 0., 0.);
for (int i = 0; i < vertices.size(); i++) {
float x = vertices[i][0];
float y = vertices[i][1];
float z = vertices[i][2];
float lon = atan2(y, x);
float lat = atan2(z, sqrt(x*x+y*y));
float u = (lon + M_PI)/(2*M_PI);
float v = (log(tan(lat/2 + M_PI/4)) + M_PI)/(2*M_PI);
uv.push_back(Vector2(u,v));
}
}
Here is my .frag file:
layout (std140) uniform camera
{
mat4 projection; /*camera's projection matrix*/
mat4 view; /*camera's view matrix*/
mat4 pvm; /*camera's projection*view*model matrix*/
mat4 ortho; /*camera's ortho projection matrix*/
vec4 position; /*camera's position in world space*/
};
in vec3 vtx_pos;
in vec4 vtx_color;
in vec3 vtx_nml;
in vec2 vtx_uv;
/*output variables*/
out vec4 frag_color;
void main()
{
vec3 col = vec3(1.0);
int numCheckers = 8;
int checkerNumber = int(floor(vtx_uv.x * numCheckers));
checkerNumber += int(floor(vtx_uv.y * numCheckers));
if (mod(checkerNumber,2) == 0) col = col * 0;
frag_color = vec4(col, 1.0);
}
I think there is something wrong with when I wrap around between UV being 0 and 1, but I'm not sure how I could assign 2 uvs in my .frag or .cpp file.

Problem with Shader "The shader uses varying --- but previous shader does not write to it"

Does anyone know why I keep getting the error that says:
The ♦ shader uses varying _I;DATA;g_mapCoord, but previous shader does not write to it.
The ♦ shader uses varying _I;DATA;worldPosition, but previous shader does not write to it.
Take a look at my shaders here.
Vertex
#version 430
layout (location = 0) in vec2 position0;
out DATA {
vec2 v_mapCoord;
vec3 worldPosition;
} Out;
uniform vec3 u_cameraPosition;
uniform mat4 u_localMatrix;
uniform mat4 u_worldMatrix;
uniform float u_scaleY;
uniform int u_lod;
uniform vec2 u_index;
uniform float u_gap;
uniform vec2 u_location;
uniform sampler2D s_heightmap;
uniform int u_lodMorphArea[8];
float morphLatitude(vec2 position)
{
//not important code
return 0;
}
float morphLongitude(vec2 position)
{
//not important code
return 0;
}
vec2 morph(vec2 localPosition, int morph_area){
//not important code
return vec2(0);
}
void main()
{
vec2 localPosition = (u_localMatrix * vec4(position0.x,0,position0.y,1)).xz;
if (u_lod > 0) {
localPosition += morph(localPosition, u_lodMorphArea[u_lod-1]); // Translate position by morphing vector
}
float height = texture(s_heightmap, localPosition).r;
Out.v_mapCoord = localPosition;
vec4 _worldPosition = u_worldMatrix * vec4(localPosition.x, height, localPosition.y,1);
Out.worldPosition = _worldPosition.xyz;
gl_Position = u_worldMatrix * vec4(localPosition.x, height, localPosition.y,1);
}
Fragment
#version 430
layout (location = 0) out vec4 outputColor;
in DATA {
vec2 g_mapCoord;
vec3 worldPosition;
} In;
const vec3 lightDirection = vec3(-0.2, -1.0, -0.2);
const float intensity = 1.2;
uniform sampler2D s_textureNormal;
uniform sampler2D s_textureWater;
uniform sampler2D s_textureLand;
float diffuse(vec3 direction, vec3 normal, float intensity)
{
return max(0.01, dot(normal, -direction) * intensity);
}
void main()
{
vec3 normal = texture(s_textureNormal, In.g_mapCoord).rgb;
float diff = diffuse(lightDirection, normal, intensity);
outputColor = vec4(1,0,0,1);
}
Geom
#version 430
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
in vec2 te_mapCoord[];
out vec2 g_mapCoord;
uniform mat4 u_viewProjection;
void main() {
for (int i = 0; i < gl_in.length(); ++i)
{
vec4 position = gl_in[i].gl_Position;
gl_Position = u_viewProjection * position;
g_mapCoord = te_mapCoord[i];
EmitVertex();
}
EndPrimitive();
}
TCS
#version 430
layout(vertices = 16) out;
in DATA {
vec2 v_mapCoord;
vec3 worldPosition;
} In[];
out vec2 tc_mapCoord[];
const int AB = 2;
const int BC = 3;
const int CD = 0;
const int DA = 1;
uniform int u_tessellationFactor;
uniform float u_tessellationSlope;
uniform float u_tessellationShift;
uniform vec3 u_cameraPosition;
// Calculate tessellation levels
float lodFactor(float dist)
{
float tessellationLevel = max(0.0, u_tessellationFactor/pow(dist, u_tessellationSlope) + u_tessellationShift);
return tessellationLevel;
}
void main()
{
if (gl_InvocationID == 0){
// Calculate mid points of the edges of the quad
vec3 abMid = vec3(gl_in[0].gl_Position + gl_in[3].gl_Position)/2.0; //Bottom left, Bottom right
vec3 bcMid = vec3(gl_in[3].gl_Position + gl_in[15].gl_Position)/2.0; //Bottom right Top right
vec3 cdMid = vec3(gl_in[15].gl_Position + gl_in[12].gl_Position)/2.0; //Top right, Top left
vec3 daMid = vec3(gl_in[12].gl_Position + gl_in[0].gl_Position)/2.0; //Top left, Bottom left
// Calculate distance between camera and mid points of the edges of the quad
float distanceAB = distance(abMid, u_cameraPosition);
float distanceBC = distance(bcMid, u_cameraPosition);
float distanceCD = distance(cdMid, u_cameraPosition);
float distanceDA = distance(daMid, u_cameraPosition);
// Tesselation levels used by tessellation primitive generator (define how much tessellation to apply to the patch). Value between 1 and gl_MaxTessGenLevel, depending on lodFactor.
gl_TessLevelOuter[AB] = mix(1, gl_MaxTessGenLevel, lodFactor(distanceAB));
gl_TessLevelOuter[BC] = mix(1, gl_MaxTessGenLevel, lodFactor(distanceBC));
gl_TessLevelOuter[CD] = mix(1, gl_MaxTessGenLevel, lodFactor(distanceCD));
gl_TessLevelOuter[DA] = mix(1, gl_MaxTessGenLevel, lodFactor(distanceDA));
gl_TessLevelInner[0] = (gl_TessLevelOuter[BC] + gl_TessLevelOuter[DA])/4;
gl_TessLevelInner[1] = (gl_TessLevelOuter[AB] + gl_TessLevelOuter[CD])/4;
}
tc_mapCoord[gl_InvocationID] = In[gl_InvocationID].v_mapCoord; // Just pass to the next stage
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}
TES
#version 430
layout(quads, fractional_odd_spacing, cw) in;
in vec2 tc_mapCoord[];
out vec2 te_mapCoord;
uniform sampler2D s_heightmap;
uniform float u_scaleY;
void main(){
float u = gl_TessCoord.x;
float v = gl_TessCoord.y;
// Compute new position for each tessellated vertex within the patch. gl_in with index 12, 0, 3, 15 are corners of the patch.
vec4 position = ((1 - u) * (1 - v) * gl_in[12].gl_Position + u * (1 - v) * gl_in[0].gl_Position + u * v * gl_in[3].gl_Position +(1 - u) * v * gl_in[15].gl_Position);
vec2 mapCoord = ((1 - u) * (1 - v) * tc_mapCoord[12] + u * (1 - v) * tc_mapCoord[0] + u * v * tc_mapCoord[3] +(1 - u) * v * tc_mapCoord[15]);
float height = texture(s_heightmap, mapCoord).r;
height *= u_scaleY;
position.y = height;
te_mapCoord = mapCoord;
gl_Position = position;
}
Can anyone help me find the error here which is why I'm getting that error message?
When you introduce a geometry shader you need to pass the varyings for the fragment shader from the geometry shader, not the vertex shader.
You can see how your geometry shader doing this:
out vec2 g_mapCoord;
is incompatible with your fragment shader expecting this:
in DATA {
vec2 g_mapCoord;
vec3 worldPosition;
} In;
Related question and subsequent answers here.

Object not moving according to mouse position when using shaders in raylib

I'm creating a few glowing particles in raylib using shaders and the particles are supposed to move along with the mouse but when compiling it gets stuck to the bottom left corner and the particles dont move.
How it Looks
The c++ code
#include <raylib.h>
#include <vector>
const int W = 400;
const int H = 400;
std::vector<Vector2> particle;
float remap(float value, float low1, float high1, float low2, float high2) {
return low2 + (value - low1) * (high2 - low2) / (high1 - low1);
}
int main() {
SetConfigFlags( FLAG_WINDOW_RESIZABLE );
InitWindow(W, H, "FireWorks");
Shader shader = LoadShader("../assets/vert.glsl", "../assets/frag.glsl");
Texture2D texture = LoadTextureFromImage(GenImageColor(W, H, BLUE));
int resolLoc = GetShaderLocation(shader, "resolution");
int particleLoc = GetShaderLocation(shader, "particle");
int particleCountLoc = GetShaderLocation(shader, "particleCount");
float res[2] = {(float)W, (float)H};
SetShaderValue(shader, resolLoc, res, SHADER_UNIFORM_VEC2);
SetTargetFPS(60);
while (!WindowShouldClose()) {
BeginDrawing();
ClearBackground(BLACK);
particle.push_back(Vector2{(float)GetMouseX(), (float)GetMouseY()});
int removeCount = 1;
for (int i = 0; i < removeCount; i++) {
if (particle.size() == 0) break;
if (particle.size() > 30) {
particle.erase(particle.begin() + i);
}
}
BeginShaderMode(shader);
float particles[30][2];
for ( int i = 0; i < particle.size(); i++) {
particles[i][0] = remap(particle[i].x, 0, W, 0.0, 1.0);
particles[i][1] = remap(particle[i].y, 0, H, 1.0, 0.0);
}
int pSize = particle.size();
SetShaderValue(shader, particleCountLoc, &pSize, SHADER_UNIFORM_INT);
SetShaderValue(shader, particleLoc, particles, SHADER_UNIFORM_VEC2);
DrawTextureRec(texture, (Rectangle) { 0, 0, (float)texture.width, (float) -texture.height }, (Vector2) { 0, 0}, RAYWHITE);
DrawRectangle(0, 0, W, H, BLACK);
EndShaderMode();
EndDrawing();
}
UnloadTexture(texture);
UnloadShader(shader);
CloseWindow();
return 0;
}
The Vertex Shader
#version 330
// Input vertex attributes
in vec3 vertexPosition;
in vec2 vertexTexCoord;
in vec3 vertexNormal;
in vec4 vertexColor;
// Input uniform values
uniform mat4 mvp;
// 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 = mvp * vec4(vertexPosition, 1.0);
}
The Fragment Shader
#version 330
// Input vertex attributes (from vertex shader)
in vec2 fragTexCoord;
in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
// NOTE: Add here your custom variables
uniform vec2 resolution;
uniform int particleCount;
uniform vec2 particle[30];
void main() {
// Texel color fetching from texture sampler
vec4 texelColor = texture(texture0, fragTexCoord);
vec2 st = gl_FragCoord.xy / resolution.xy;
float r = 0.0;
float g = 0.0;
float b = 0.0;
for (int i = 0; i < 30; i++) {
if (i < particleCount) {
vec2 particlePos = particle[i];
float value = float(i) / distance(st, particlePos.xy) * 0.00015;
g += value * 0.5;
b += value;
}
}
finalColor = vec4(r, g, b, 1.0) * texelColor * colDiffuse;
}
The JS version of the code (which works) is here.
If you could point me in the right direction it'd be great.
The uniform particle is of type vec2[30]. An uniform array can needs to be set with SetShaderValueV instead of SetShaderValue:
SetShaderValue(shader, particleLoc, particles, SHADER_UNIFORM_VEC2);
SetShaderValueV(shader, particleLoc, particles[0], SHADER_UNIFORM_VEC2, 30);

GLSL Water shader normals morph as light passes over?

I decided to follow the classic guide for writing a basic GLSL water shaders using the sum of sines method. I attempted to implement it inside of Processing 5, where I made a field of vertices in a PShape to make a mesh to mess with. I then overwrote the default shaders with my own vertex and fragment shaders, and I dropped in a directional light so I can actually see the normals. I made sure the directional light was movable as well so I could see if the normals work from all angles.
I got the waves to form height correctly and I had some form of normals workings, but the normals are interacting really strange. When my light passes across the center axis of my water plane, the normals seem to morph between the different waves and change based on the light angle. The gif I captured was too large to post in line, so I'm sure seeing it would explain better than my words:
https://imgur.com/PCznL7U
You should maximize the link to see the whole picture. Note how as the light pans from left to right, the normals of the waves seem to morph between two sets? This is especially apparent as it crosses center. It's like the normals are inconsistent based on the direction the object is being lit from.
The sphere in the middle is a normal sphere using the standard Processing shader. I left it there as reference to see the waves as well as confirm where my lighting was and that it was working fine.
Any ideas what I did wrong? I know I did some math incorrectly somewhere.
EDIT: Was recommended I added the (lengthy) source code [which I should have done from the start].
Vertex Shader:
#define PROCESSING_LIGHT_SHADER
#define MAXWAVES 6
const float pi = 3.14159;
uniform mat4 transform;
uniform mat4 modelview;
uniform mat3 normalMatrix;
uniform float time; //Time since shader started
attribute vec4 position; //Position the vertex from Processing
attribute vec4 color; //Color of the vertex from Processing
attribute vec3 normal; //Normal of the vertex from Processing
attribute vec4 ambient;
attribute vec4 specular;
attribute vec4 emissive;
attribute float shininess;
varying vec4 vertColor; //Color passed on to fragment shader
varying vec4 backVertColor; //Color passed on to fragment shader
uniform float waveLength[MAXWAVES]; //Length of wave
uniform float speed[MAXWAVES]; //Cycle speed of wave
uniform float amplitude[MAXWAVES]; //Wave cycle height
uniform float xDirection[MAXWAVES];
uniform float yDirection[MAXWAVES]; //Flow vector of wave
uniform int lightCount;
uniform vec4 lightPosition[8];
uniform vec3 lightNormal[8];
uniform vec3 lightAmbient[8];
uniform vec3 lightDiffuse[8];
uniform vec3 lightSpecular[8];
uniform vec3 lightFalloff[8];
uniform vec2 lightSpot[8];
varying vec3 Normal;
varying vec3 FragPos;
varying vec3 Vec;
varying vec3 lightDir;
//Some constants that the processing shader used
const float zero_float = 0.0;
const float one_float = 1.0;
const vec3 zero_vec3 = vec3(0);
float falloffFactor(vec3 lightPos, vec3 vertPos, vec3 coeff) {
vec3 lpv = lightPos - vertPos;
vec3 dist = vec3(one_float);
dist.z = dot(lpv, lpv);
dist.y = sqrt(dist.z);
return one_float / dot(dist, coeff);
}
float spotFactor(vec3 lightPos, vec3 vertPos, vec3 lightNorm, float minCos, float spotExp) {
vec3 lpv = normalize(lightPos - vertPos);
vec3 nln = -one_float * lightNorm;
float spotCos = dot(nln, lpv);
return spotCos <= minCos ? zero_float : pow(spotCos, spotExp);
}
float lambertFactor(vec3 lightDir, vec3 vecNormal) {
return max(zero_float, dot(lightDir, vecNormal));
}
float blinnPhongFactor(vec3 lightDir, vec3 vertPos, vec3 vecNormal, float shine) {
vec3 np = normalize(vertPos);
vec3 ldp = normalize(lightDir - np);
return pow(max(zero_float, dot(ldp, vecNormal)), shine);
}
//Returns the height of a vertex given a single wave param
float WaveHeight(int waveNumber, float x, float y) {
vec2 direction = (vec2(xDirection[waveNumber], yDirection[waveNumber]));
float frequency = 2.0*pi/waveLength[waveNumber];
float phase = speed[waveNumber] * frequency;
float theta = dot(direction, vec2(x, y));
return amplitude[waveNumber] * sin(theta * frequency + time * phase);
}
//Returns height of a vertex given all the active waves
// and its current x/y value
float WaveSum(float x, float y)
{
float height = 0.0;
for(int i = 0; i < MAXWAVES; i++)
{
height += WaveHeight(i, x, y);
}
return height;
}
float getDy(int waveNumber, float x, float y) {
vec2 direction = (vec2(xDirection[waveNumber], yDirection[waveNumber]));
float frequency = 2.0*pi/waveLength[waveNumber];
float phase = speed[waveNumber] * frequency;
float theta = dot(direction, vec2(x, y));
float A = amplitude[waveNumber] * direction.y * frequency;
return A * cos(theta * frequency + time * phase);
}
float getDx(int waveNumber, float x, float y) {
vec2 direction = (vec2(xDirection[waveNumber], yDirection[waveNumber]));
float frequency = 2.0*pi/waveLength[waveNumber];
float phase = speed[waveNumber] * frequency;
float theta = dot(direction, vec2(x, y));
float A = amplitude[waveNumber] * direction.x * frequency;
return A * cos(theta * frequency + time * phase);
}
//Returns the normal vector for each vertex
vec3 getNormal(float x, float y) {
float dx = 0.0;
float dy = 0.0;
//Sum for each wave
for (int i = 0; i < MAXWAVES; i++) {
dx += getDx(i, x, y);
dy += getDy(i, x, y);
}
vec3 n = vec3(-dx, -dy, 1.0);
return normalize(n);
}
void main() {
vec4 pos = position; //Grab the position from Processing bc it's read only
pos.z = WaveSum(pos.x, pos.y);
gl_Position = transform * pos; //Get clipping matrix for view
vec3 ecVertex = vec3(modelview * pos);
// Normal vector in eye coordinates
vec3 Normal = getNormal(pos.x, pos.y);
vec3 ecNormal = normalize(normalMatrix * Normal);
vec3 ecNormalInv = ecNormal * -one_float;
// Light calculations
vec3 totalAmbient = vec3(0, 0, 0);
vec3 totalFrontDiffuse = vec3(0, 0, 0);
vec3 totalFrontSpecular = vec3(0, 0, 0);
vec3 totalBackDiffuse = vec3(0, 0, 0);
vec3 totalBackSpecular = vec3(0, 0, 0);
for (int i = 0; i < 8; i++) {
if (lightCount == i) break;
vec3 lightPos = lightPosition[i].xyz;
bool isDir = lightPosition[i].w < one_float;
float spotCos = lightSpot[i].x;
float spotExp = lightSpot[i].y;
vec3 lightDir;
float falloff;
float spotf;
if (isDir) {
falloff = one_float;
lightDir = -one_float * lightNormal[i];
} else {
falloff = falloffFactor(lightPos, ecVertex, lightFalloff[i]);
lightDir = normalize(lightPos - ecVertex);
}
spotf = spotExp > zero_float ? spotFactor(lightPos, ecVertex, lightNormal[i],
spotCos, spotExp)
: one_float;
if (any(greaterThan(lightAmbient[i], zero_vec3))) {
totalAmbient += lightAmbient[i] * falloff;
}
if (any(greaterThan(lightDiffuse[i], zero_vec3))) {
totalFrontDiffuse += lightDiffuse[i] * falloff * spotf *
lambertFactor(lightDir, ecNormal);
totalBackDiffuse += lightDiffuse[i] * falloff * spotf *
lambertFactor(lightDir, ecNormalInv);
}
if (any(greaterThan(lightSpecular[i], zero_vec3))) {
totalFrontSpecular += lightSpecular[i] * falloff * spotf *
blinnPhongFactor(lightDir, ecVertex, ecNormal, shininess);
totalBackSpecular += lightSpecular[i] * falloff * spotf *
blinnPhongFactor(lightDir, ecVertex, ecNormalInv, shininess);
}
}
// Calculating final color as result of all lights (plus emissive term).
// Transparency is determined exclusively by the diffuse component.
vertColor =
vec4(totalFrontDiffuse, 1) * color;
backVertColor =
vec4(totalBackDiffuse, 1) * color;
}
Fragment Shader:
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
varying vec4 vertColor; //Color from vertshader
varying vec4 backVertColor; //Color from vertshader
void main() {
gl_FragColor = gl_FrontFacing ? vertColor : backVertColor;
}

Problems with drawing billboards

I am currently trying to draw billboards and some geometry with "modern opengl approach". Problem is that I cannot force billboards to keep their positions in space.
I need to link text positions with positions of another objects. Coordinates of text position are (3,3,3) and same coordinates has end of black line. In some positions I have exactly what I need: text is drawn at the end of line, but in some - it is too far from the end of line.
My render code:
public void Draw()
{
//Set up matrices
projectionMatrix = Matrix4.CreateOrthographic(_width, _height, -10000, 10000);
modelMatrix = Matrix4.Identity;
viewMatrix = Matrix4.CreateRotationY((float)xrot) *
Matrix4.CreateRotationX((float)yrot) *
Matrix4.CreateScale((float)scale);
var viewPort = new Rectangle(-(_width / 2), -(_height / 2), _width, _height);
var viewportTransformationMatrix = ComputeViewportTransformationMatrix(viewPort, -100, 100);
var viewportOrthographicMatrix = ComputeViewportOrthographicMatrix(viewPort);
worldViewProj = modelMatrix * viewMatrix * projectionMatrix;
//DRAW AXISES
GL.UseProgram(axisesProgramID);
axisesProgram.Uniforms["worldViewProj"].SetValue(worldViewProj);
axisesVAO.Bind();
for (int i = 0; i < 4; i++)
{
GL.DrawArrays(PrimitiveType.Lines, i * 2, 2);
}
//DRAW TEXT WITH PRE-CREATED TEXTURE
GL.UseProgram(textProgramID);
GL.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, textureID);
//set-up uniforms
textProgram.Uniforms["og_viewportOrthographicMatrix"].SetValue(viewportOrthographicMatrix);
textProgram.Uniforms["og_viewportTransformationMatrix"].SetValue(viewportTransformationMatrix);
textProgram.Uniforms["Position"].SetValue(new float[] { 3.0f, 3.0f, 3.0f });
textProgram.Uniforms["projectionMatrix"].SetValue(projectionMatrix);
textProgram.Uniforms["modelViewMatrix"].SetValue(modelViewMatrix);
textProgram.Uniforms["og_texture0"].SetValue(0);
GL.DrawArrays(PrimitiveType.Points, 0, 1);
GL.BindTexture(TextureTarget.Texture2D, 0);
}
public Matrix4 ComputeViewportTransformationMatrix(Rectangle viewport, float nearDepthRange, float farDepthRange)
{
double halfWidth = viewport.Width * 0.5;
double halfHeight = viewport.Height * 0.5;
double halfDepth = (farDepthRange - nearDepthRange) * 0.5;
//
// Bottom and top swapped: MS -> OpenGL
//
return new Matrix4(
(float)halfWidth, 0.0f, 0.0f, (float)viewport.Left + (float)halfWidth,
0.0f, (float)halfHeight, 0.0f, (float)viewport.Top + (float)halfHeight,
0.0f, 0.0f, (float)halfDepth, (float)nearDepthRange + (float)halfDepth,
0.0f, 0.0f, 0.0f, 1.0f);
}
public static Matrix4 ComputeViewportOrthographicMatrix(Rectangle viewport)
{
//
// Bottom and top swapped: MS -> OpenGL
//
return Matrix4.CreateOrthographicOffCenter(
(float)viewport.Left, (float)viewport.Right,
(float)viewport.Top, (float)viewport.Bottom,
0.0f, 1.0f);
}
My axises shaders are really simple path-through.
//VERTEX SHADER
#version 150 core
in vec3 in_Position;
in vec3 in_Color;
out vec4 color;
uniform mat4 worldViewProj;
void main(void) {
gl_Position = worldViewProj * vec4(in_Position, 1.0);
color = vec4(in_Color, 1.0f);
}
//FRAGMENT SHADER
#version 150 core
in vec4 color;
out vec4 out_Color;
void main(void)
{
out_Color = color;
}
Here are text (texture) shaders:
//VERTEX SHADER
#version 330
out float gsOrigin;
out vec2 gsPixelOffset;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 og_viewportTransformationMatrix;
uniform float origin = 6; // TODO: Why does this not work when float is int?
uniform vec2 pixelOffset = vec2(0,0);
uniform vec3 Position;
vec4 ModelToWindowCoordinates(
vec4 v,
mat4 modelViewPerspectiveMatrix,
mat4 viewportTransformationMatrix)
{
v = modelViewPerspectiveMatrix * v; // clip coordinates
v.xyz /= v.w; // normalized device coordinates
v.xyz = (viewportTransformationMatrix * vec4(v.xyz, 1.0)).xyz; // window coordinates
return v;
}
void main()
{
gl_Position = ModelToWindowCoordinates ( vec4(Position, 1.0f) , modelViewMatrix * projectionMatrix , og_viewportTransformationMatrix ) ;
gsOrigin = origin;
gsPixelOffset = pixelOffset;
}
//GEOMETRY SHADER
#version 330
layout(points) in;
layout(triangle_strip, max_vertices = 4) out;
in float gsOrigin[];
in vec2 gsPixelOffset[];
out vec2 fsTextureCoordinates;
uniform sampler2D og_texture0;
uniform float og_highResolutionSnapScale;
uniform mat4 og_viewportOrthographicMatrix;
void main()
{
float originScales[3] = float[](0.0, 1.0, -1.0);
vec2 halfSize = vec2(textureSize(og_texture0, 0)) * 0.5 * og_highResolutionSnapScale;
vec4 center = gl_in[0].gl_Position;
int horizontalOrigin = int(gsOrigin[0]) & 3; // bits 0-1
int verticalOrigin = (int(gsOrigin[0]) & 12) >> 2; // bits 2-3
center.xy += (vec2(originScales[horizontalOrigin], originScales[verticalOrigin]) * halfSize);
center.xy += (gsPixelOffset[0] * og_highResolutionSnapScale);
vec4 v0 = vec4(center.xy - halfSize, 0, 1.0);
vec4 v1 = vec4(center.xy + vec2(halfSize.x, -halfSize.y), 0, 1.0);
vec4 v2 = vec4(center.xy + vec2(-halfSize.x, halfSize.y), 0, 1.0);
vec4 v3 = vec4(center.xy + halfSize, 0, 1.0);
gl_Position = og_viewportOrthographicMatrix * v0;
fsTextureCoordinates = vec2(0.0, 0.0);
EmitVertex();
gl_Position = og_viewportOrthographicMatrix * v1;
fsTextureCoordinates = vec2(1.0, 0.0);
EmitVertex();
gl_Position = og_viewportOrthographicMatrix * v2;
fsTextureCoordinates = vec2(0.0, 1.0);
EmitVertex();
gl_Position = og_viewportOrthographicMatrix * v3;
fsTextureCoordinates = vec2(1.0, 1.0);
EmitVertex();
}
//FRAGMENT SHADER
#version 330
in vec2 fsTextureCoordinates;
out vec4 fragmentColor;
uniform sampler2D og_texture0;
uniform vec3 u_color;
void main()
{
vec4 color = texture(og_texture0, fsTextureCoordinates);
if (color.a == 0.0)
{
discard;
}
fragmentColor = vec4(color.rgb * u_color.rgb, color.a);
}
To me it looks like there is some basic coordinate system confusion. I have not checked everything here, but to me,
worldViewProj = modelMatrix * viewMatrix * projectionMatrix;
looks like the wrong way round, as vertices should be multiplied from the right like
projection*view*model*vertex
The same issue is within your shaders.
Also, i am not entirely sure, but it seems you are computing pixel coordinates for gl_Position in the shader (as you are applying some viewporttransform in the function ModelToWindowCoordinates). Since pixel coordinates may e.g. range from 0,0 to 1920,1080 they are not correct for gl_Position, which should be in clip coordinates.
I think you should read up a good tutorial about 3d billboarding and the math, for example
this one looks quite interesting. Then modify the sample code to fit your needs step by step.