Vertex Shader compile failure, no error - opengl

My shader is throwing an error when compiling, but it isn't returning an error log. Any idea why?
#version 430
layout(location = 0) in vec3 vertex_position;
layout(location = 1) in vec2 vertex_texcoord;
layout(location = 2) in vec3 vertex_pos;
layout(location = 3) in vec3 vertex_rot;
layout(location = 4) in vec3 vertex_scl;
layout(location = 5) in int vertex_texnum;
varying vec2 texcoord;
varying float tex_num;
uniform float aspect_ratio;
mat4 view_frustum(
float angle_of_view,
float aspect_ratio,
float z_near,
float z_far
) {
return mat4(
vec4(1.0/tan(angle_of_view), 0.0, 0.0, 0.0),
vec4(0.0, aspect_ratio/tan(angle_of_view), 0.0, 0.0),
vec4(0.0, 0.0, (z_far+z_near)/(z_far-z_near), -2.0*z_far*z_near/(z_far-z_near)),
vec4(0.0, 0.0, 1.0, 0.0)
);
}
mat4 scale(float x, float y, float z)
{
return mat4(
vec4(x, 0.0, 0.0, 0.0),
vec4(0.0, y, 0.0, 0.0),
vec4(0.0, 0.0, z, 0.0),
vec4(0.0, 0.0, 0.0, 1.0)
);
}
mat4 translate(float x, float y, float z)
{
return mat4(
vec4(1.0, 0.0, 0.0, 0.0),
vec4(0.0, 1.0, 0.0, 0.0),
vec4(0.0, 0.0, 1.0, 0.0),
vec4(x, y, z, 1.0)
);
}
mat4 rotate_x(float theta)
{
return mat4(
vec4(1.0, 0.0, 0.0, 0.0),
vec4(0.0, cos(theta), sin(theta), 0.0),
vec4(0.0, -sin(theta), cos(theta), 0.0),
vec4(0.0, 0.0, 0.0, 1.0)
);
}
mat4 rotate_y(float theta)
{
return mat4(
vec4( cos(theta), 0.0, sin(theta), 0.0),
vec4( 0.0, 1.0, 0.0, 0.0),
vec4(-sin(theta), 0.0, cos(theta), 0.0),
vec4( 0.0, 0.0, 0.0, 1.0)
);
}
mat4 rotate_z(float theta)
{
return mat4(
vec4(cos(theta), -sin(theta), 0.0, 0.0),
vec4(sin(theta), cos(theta), 0.0, 0.0),
vec4( 0.0, 0.0, 1.0, 0.0),
vec4( 0.0, 0.0, 0.0, 1.0)
);
}
mat4 frustum = view_frustum(radians(45.0), 1, 0.5, 50.0);
mat4 translation = translate(vertex_pos.x, vertex_pos.y, vertex_pos.z);
mat4 rotation = rotate_x(vertex_rot.x) * rotate_y(vertex_rot.y) * rotate_z(vertex_rot.z);
mat4 scale = scale(vertex_scl.x, vertex_scl.y, vertex_scl.z);
void main () {
gl_Position = frustum * (rotation * (scale * (translation * vec4(vertex_position, 1.0))));
texcoord = vertex_texcoord;
tex_num = vertex_texnum;
}
EDIT: My apologies for the uninformative question, I was sleep deprived.
My shader loading code is here:
void initShaders(GLuint& shader_program) {
std::ifstream file;
std::string line;
file.open("data/shaders/VertexShader.glsl", std::ios::in);
if(!file.is_open()) Error("Failed to open Vertex Shader file.");
std::string vs_str = "";
int i = 0;
while(getline(file,line)) {
vs_str += line + "\n";
++i;
}
std::string fs_str = "";
file.close();
file.open("data/shaders/FragmentShader.glsl", std::ios::in);
if(!file.is_open()) Error("Failed to open Fragment Shader file.");
i = 0;
while(getline(file,line)) {
fs_str += line + "\n";
++i;
}
const char* vertex_shader = &vs_str[0];
const char* fragment_shader = &fs_str[0];
file.close();
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, &vertex_shader, NULL);
glCompileShader(vs);
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, &fragment_shader, NULL);
glCompileShader(fs);
GLint isCompiled = 0;
glGetShaderiv(vs, GL_COMPILE_STATUS, &isCompiled);
if(isCompiled == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(vs, GL_INFO_LOG_LENGTH, &maxLength);
// The maxLength includes the NULL character
std::vector<GLchar> errorLog(maxLength);
glGetShaderInfoLog(vs, maxLength, &maxLength, &errorLog[0]);
std::cout << "VERTEX SHADER ERROR:\n";
for (std::vector<GLchar>::iterator i = errorLog.begin(); i != errorLog.end(); ++i)
{
std::cout << *i;
}
std::cout << "\n";
glDeleteShader(vs); // Don't leak the shader.
quit(EXIT_FAILURE);
}
isCompiled = 0;
glGetShaderiv(fs, GL_COMPILE_STATUS, &isCompiled);
if(isCompiled == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(fs, GL_INFO_LOG_LENGTH, &maxLength);
// The maxLength includes the NULL character
std::vector<GLchar> errorLog(maxLength);
glGetShaderInfoLog(fs, maxLength, &maxLength, &errorLog[0]);
std::cout << "FRAGMENT SHADER ERROR:\n";
for (std::vector<GLchar>::iterator i = errorLog.begin(); i != errorLog.end(); ++i)
{
std::cout << *i;
}
std::cout << "\n";
glDeleteShader(fs); // Don't leak the shader.
quit(EXIT_FAILURE);
}
shader_program = glCreateProgram();
glAttachShader(shader_program, fs);
glAttachShader(shader_program, vs);
glLinkProgram(shader_program);
glUseProgram(shader_program);
}

For me, the shader has a lot of text in the compile log (tested on OpenGL 4.3 Core):
0(10) : warning C7555: 'varying' is deprecated, use 'in/out' instead
0(11) : warning C7555: 'varying' is deprecated, use 'in/out' instead
0(82) : error C1002: the name "scale" is already defined at 0(29)
0(29) : error C1054: initialization of non-variable "scale"
0(85) : error C1020: invalid operands to "*"
The first two errors are because the keyword varying is not used in 430 anymore. You'll have to replace it with out in the vertex shader and with in in the fragment shader.
The 3rd error is because you are naming a variable with the same name as a function (both are named scale), while the 4 and 5 error are follow-up errors due to 3.
Since it seems that your shader loader does not work well, I would suggest you to ask a new question containing the shader loader code.

Related

Draw two shapes on top of each other in geometry shader?

With this small program I want to achieve:
Publish a point
Transform this point with vertex shader
Create a square and a triangle with geometry shader
Fill both the triangle and the square with fragment shader
Unfortunately, I cannot manage to superpose both shapes. I see either only the triangle or only the square. I tried to play with z but it doesn't change anything.
void main(void) {
finalColour = vec4(1.0, 0.5, 0.5, 1.0);
square(1.0, 0.0);
finalColour = vec4(0.0, 1.0, 1.0, 0.0);
triangle(vec3(0.0, 0.0, 0.0), angle[0], 1.0);
EndPrimitive();
}
void main(void) {
// finalColour = vec4(1.0, 0.5, 0.5, 1.0);
// square(1.0, 0.0);
finalColour = vec4(0.0, 1.0, 1.0, 0.0);
triangle(vec3(0.0, 0.0, 0.0), angle[0], 1.0);
EndPrimitive();
}
Main
#include <SFML/Graphics.hpp>
#include <GL/glew.h>
#include <vector>
#define WIDTH 800
int main() {
sf::RenderWindow window(sf::VideoMode(WIDTH, WIDTH), "Test");
sf::Shader shader;
shader.loadFromFile("shader.vert", "shader.geom", "shader.frag");
sf::Transform matrix = sf::Transform::Identity;
matrix.scale(1.0 / WIDTH, 1.0 / WIDTH);
sf::Glsl::Mat4 projectionViewMatrix = matrix;
shader.setUniform("projectionViewMatrix", projectionViewMatrix);
std::vector<GLfloat> vertices;
vertices.push_back(0.0); vertices.push_back(0.0); vertices.push_back(0.0);
while (window.isOpen()) {
sf::Event currEvent;
while (window.pollEvent(currEvent)) {
switch (currEvent.type) {
case(sf::Event::Closed):
window.close(); break;
}
}
window.clear(sf::Color::Black);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glVertexPointer(3, GL_FLOAT, 0, vertices.data());
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_POINTS, 0, vertices.size() / 3);
glDisableClientState(GL_VERTEX_ARRAY);
sf::Shader::bind(&shader);
window.display();
}
}
Vertex
#version 150
in vec3 position;
out float angle;
uniform mat4 projectionViewMatrix;
void main(void){
gl_Position = projectionViewMatrix * vec4(position.xy, 0.0 ,1.0);
angle = position.z;
}
Geometry
#version 150
layout (points) in;
layout (triangle_strip, max_vertices = 6) out;
in float angle[];
out vec4 finalColour;
uniform mat4 projectionViewMatrix;
void createVertex(vec3 offset) {
vec4 actualOffset = vec4(offset, 1.0);
vec4 worldPosition = gl_in[0].gl_Position + actualOffset;
gl_Position = worldPosition;
EmitVertex();
}
void createAngularVertex(vec3 offset, float angle, float radius) {
vec4 actualOffset = vec4(offset, 1.0);
vec4 worldPosition = gl_in[0].gl_Position + actualOffset;
gl_Position = worldPosition;
gl_Position.x += cos(angle) * radius;
gl_Position.y += sin(angle) * radius;
EmitVertex();
}
void square(float size, float z) {
createVertex(vec3(-size, -size, z));
createVertex(vec3(size, -size, z));
createVertex(vec3(-size, size, z));
createVertex(vec3(size, size, z));
createVertex(vec3(size, -size, z));
createVertex(vec3(-size, size, z));
EndPrimitive();
}
void triangle(vec3 offset, float angle, float radius) {
float pi = 3.1415;
float angleOffset = 0.5;
createAngularVertex(offset, angle, radius);
createAngularVertex(offset, angle + pi + angleOffset, radius);
createAngularVertex(offset, angle + pi - angleOffset, radius);
EndPrimitive();
}
void main(void) {
finalColour = vec4(1.0, 0.5, 0.5, 1.0);
square(1.0, 0.0);
finalColour = vec4(0.0, 1.0, 1.0, 0.0);
triangle(vec3(0.0, 0.0, 0.0), angle[0], 0.1);
EndPrimitive();
}
Fragment
#version 150
in vec4 finalColour;
out vec4 out_Colour;
void main(void){
out_Colour = vec4(finalColour.rgb, 1.0);
}
The geometry shader creates 2 primitives, one with 6 vertices and one with 3 vertices, requiring a total of 9 vertices:
layout (triangle_strip, max_vertices = 6) out;
layout (triangle_strip, max_vertices = 9) out;

The Geometry Shader is duplicating Shapes (in Processing)

I'm trying to generate a simple shape with a Geometry Shader, but the shape is rendering twice and I don't know why.
First we have a really simple Vertex Shader
#version 150
in vec4 position;
void main() {
gl_Position = position;
}
Then there's a Geometry Shader thats generating a simple triangle.
#version 150
layout (triangles) in;
layout (triangle_strip, max_vertices = 5) out;
out FragData {
vec4 color;
} FragOut;
void main(){
//RED TOP LEFT
FragOut.color = vec4(1.0, 0.0, 0.0, 1.0);
gl_Position = gl_in[0].gl_Position + vec4( -1.0, 0.0, 0.0, 0.0);
EmitVertex();
//BLUE BOTTOM LEFT
FragOut.color = vec4(0., 0., 1., 1.);
gl_Position = gl_in[0].gl_Position + vec4( -1.0, -1.0, 0.0, 0.0);
EmitVertex();
//GREEN BOTTOM RIGHT
FragOut.color = vec4(0.0, 1.0, 0.0, 1.0);
gl_Position = gl_in[0].gl_Position + vec4( 1.0, -1.0, 0.0, 0.0);
EmitVertex();
EndPrimitive();
}
And finally a simple Fragment Shader
#version 150
in FragData {
vec4 color;
} FragIn;
out vec4 fragColor;
void main() {
fragColor = FragIn.color;
}
The result should be a triangle, but TWO triangles are being rendered:
Here's the result
The Geometry Shader is executed once for each primitive. A rect() consists of 2 triangles, so the geometry shader is executed twice and generates 2 triangle_strip primitives.
Draw a single POINTS primitive instead of the rectangle:
beginShape(POINTS);
vertex(x, y);
endShape();
Note that you need to change the Primitive input specification:
layout (triangles) in;
layout (points) in;

Use two Uniforms in Vertex Shader

was following the OpenGL RedBook and was able to use a Uniform for a frustrum or translate matrix. I have become a little lost trying to use both at the same time.
//Declarations
GLfloat frustum[4][4] = {
{((2.0*frusZNe //Etc...
GLfloat translate[4][4] = {
{1.0, 0.0, //Etc...
And then I use it in Init:
GLuint uboIndex;
GLint uboSize;
GLuint ubo;
GLvoid *buffer;
uboIndex = glGetUniformBlockIndex(program, "frustumUniform");
glGetActiveUniformBlockiv(program, uboIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &uboSize);
buffer = malloc(uboSize);
const char* frustumName[1] = {"frustum"};
GLuint indices[1];
GLint size[1];
GLint offset[1];
GLint type[1];
glGetUniformIndices(program, 1, frustumName, indices);
glGetActiveUniformsiv(program, 1, indices, GL_UNIFORM_OFFSET, offset);
glGetActiveUniformsiv(program, 1, indices, GL_UNIFORM_SIZE, size);
glGetActiveUniformsiv(program, 1, indices, GL_UNIFORM_TYPE, type);
//memcpy(&buffer + 0, &frustum, sizeof(frustum));
glGenBuffers(1, &ubo);
glBindBuffer(GL_UNIFORM_BUFFER, ubo);
glBufferData(GL_UNIFORM_BUFFER, uboSize, &frustum, GL_STATIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, uboIndex, ubo);
Immediately afterwards, I do the same thing for the translate one but change some of the values, such as: glGetUniformBlockIndex(program, "translateUniform");
///Translate Uniform, same 20 statements as above, with alterations
GLuint uboIndex2;
GLint uboSize2;
GLuint ubo2;
GLvoid *buffer2;
uboIndex2 = glGetUniformBlockIndex(program, "translateUniform");
glGetActiveUniformBlockiv(program, uboIndex2, GL_UNIFORM_BLOCK_DATA_SIZE, &uboSize2);
buffer2 = malloc(uboSize2);
string offsetString = iToS(uboIndex2);
debugMsg(offsetString + "Index2, 1:");
const char* translateName[1] = {"translate"};
GLuint indices2[1];
GLint size2[1];
GLint offset2[1];
GLint type2[1];
glGetUniformIndices(program, 1, translateName, indices2);
glGetActiveUniformsiv(program, 1, indices2, GL_UNIFORM_OFFSET, offset2);
glGetActiveUniformsiv(program, 1, indices2, GL_UNIFORM_SIZE, size2);
glGetActiveUniformsiv(program, 1, indices2, GL_UNIFORM_TYPE, type2);
//memcpy(&buffer + 0, &frustum, sizeof(frustum));
glGenBuffers(1, &ubo2);
glBindBuffer(GL_UNIFORM_BUFFER, ubo2);
glBufferData(GL_UNIFORM_BUFFER, uboSize2, &translate, GL_STATIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, uboIndex2, ubo2);
string uboIndex2S = iToS(uboIndex2);
debugMsg("Index 2: " + uboIndex2S);
string uboSizeS, uboSizeS2, uboIndexS, uboIndexS2;
uboSizeS = iToS(uboSize);
uboSizeS2 = iToS(uboSize2);
uboIndexS = iToS(uboIndex);
uboIndexS2 = iToS(uboIndex2);
debugMsg(uboSizeS + " ," + uboSizeS2 + " ," + uboIndexS + " , " + uboIndexS2);
Vertex shader:
#version 430 core
uniform frustumUniform {
mat4 frustum;
};
uniform translateUniform {
mat4 translate;
};
layout(location = 0) in vec4 vPosition;
void
main()
{
vec3 trans = vec3(.2, 0, 0);
mat4 view = mat4(1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, -200.0, 1.0);
mat4 rotate = mat4(0.2, 0.0, 0.3, 0.0,
0.0, 1.0, 0.0, 0.0,
-0.3, 0.0, 0.2, 0.0,
0.0, 0.0, 20.0, 1.0);
mat4 translateOld = mat4(1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0);
gl_Position = frustum * translate * view * vPosition;
}
It compiles, but the second Uniform no longer works. Any ideas?

Geometry shader doesn't emit geometry

I am setting the following pipeline:
Vertex shader gets as input 4 vertices to draw as full screen quad with triangle strip :
Vertex Shader:
#version 420 core
layout(location = 0) in vec4 position;
out gl_PerVertex
{
vec4 gl_Position;
}
;
void main()
{
gl_Position = position;
}
Then I want to do some work on them in geometry shader .But for now I just try to emit the same vertices as triangle strip from the shader just to make sure it work ok.
Geom Shader
#version 420 core
layout(invocations = 1,triangles) in;
layout(triangle_strip, max_vertices =4) out;
out gl_PerVertex
{
vec4 gl_Position;
};
void main()
{
gl_Position = vec4( 1.0, 1.0, 0.0, 1.0 );
EmitVertex();
gl_Position = vec4(-1.0, 1.0, 0.0, 1.0 );
EmitVertex();
gl_Position = vec4( 1.0,-1.0, 0.0, 1.0 );
EmitVertex();
gl_Position = vec4(-1.0,-1.0, 0.0, 1.0 );
EmitVertex();
EndPrimitive();
}
And the fragment shader:
#version 420 core
layout(binding=0) uniform sampler2D COLOR_MAP_0;
out vec4 OUTPUT;
void main(void) {
OUTPUT = vec4(1,0,0,1);
}
The client side setup is like this:
glm::vec4 va[4] ={glm::vec4(1.0, 1.0, 0.0, 1.0),glm::vec4(-1.0, 1.0, 0.0, 1.0),glm::vec4( 1.0,-1.0, 0.0, 1.0),glm::vec4(-1.0,-1.0, 0.0, 1.0)};
auto ss = sizeof(va);
glGenVertexArrays(1,&_dummyVao);
glBindVertexArray(_dummyVao);
glGenBuffers(1,&_dummyPoinBuff);
glBindBuffer(GL_ARRAY_BUFFER, _dummyPoinBuff);
glBufferData(GL_ARRAY_BUFFER, ss, &va[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, ((GLubyte *)NULL + (0)));
glEnableVertexAttribArray(0);
glBindVertexArray(0);
The draw call:
glBindVertexArray(_dummyVao);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
The weird thing is that it doesn't work!The output is empty.If I switch to emit points instead ,it does emit them.The vertex data is 100% correct.it draws the quad ok if I detach the geometry shader.What can be possibly wrong here?
UPDATE:
This variation does work.
const vec2 vert_data[4] = vec2[](
vec2(-1.0, 1.0),
vec2(-1.0, -1.0),
vec2(1.0, 1.0),
vec2(1.0, -1.0)
);
for(int i=0; i<4; i++)
{
gl_Position = vec4( vert_data[i].xy,0,1);///gl_Position;
EmitVertex();
}
EndPrimitive();
Redclare of inputs / outputs in geometry shader still didn't help:
in gl_PerVertex
{
vec4 gl_Position;
} gl_in[];
out gl_PerVertex
{
vec4 gl_Position;
};

How to pass and use 4x4 transformation matrix into vShader with glUniformMatrix4fv?

Im sure there is a better way for me to calculate my transformation matrix from a quaternion but this is what i have for now. I need to pass the 16 values into the shader but am having an issue. I keep getting type incompatibility errors. Also once i get it in there do i have to do anything to it to multiply it to what i already have?
Here is my display and shader
void display()
{ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
if (trackballMove)
{
glRotatef(angle, axis[0], axis[1], axis[2]);
}
//colorcube();
glUniform3fv( theta, 1, Theta );
float a = angle;
float b = axis[0];
float c = axis[1];
float d = axis[2];
float xform[16] = {(a*a+b*b-c*c-d*d),(2*b*c-2*a*d),(2*b*d+2*a*c),0.0,
(2*b*c+2*a*d),(a*a-b*b+c*c-d*d),(2*c*d-2*a*b),0.0,
(2*b*d-2*a*c),(2*c*d+2*a*b),(a*a-b*b-c*c+d*d),0.0,
0.0,0.0,0.0,1.0};
GLuint Transform = glGetUniformLocation( program, "vTransform");
glUniformMatrix4fv(Transform, xform);
glDrawArrays( GL_TRIANGLES, 0, NumVertices );
glutSwapBuffers();
}
here is the shader
#version 150
in vec4 vPosition;
in vec4 vColor;
out vec4 color;
uniform vec3 theta;
uniform vec4 vTransform;
void main()
{
// Compute the sines and cosines of theta for each of
// the three axes in one computation.
vec3 angles = radians( theta );
vec3 c = cos( angles );
vec3 s = sin( angles );
// Remember: these matrices are column-major
mat4 rx = mat4( 1.0, 0.0, 0.0, 0.0,
0.0, c.x, -s.x, 0.0,
0.0, s.x, c.x, 0.0,
0.0, 0.0, 0.0, 1.0 );
mat4 ry = mat4( c.y, 0.0, s.y, 0.0,
0.0, 1.0, 0.0, 0.0,
-s.y, 0.0, c.y, 0.0,
0.0, 0.0, 0.0, 1.0 );
mat4 rz = mat4( c.z, -s.z, 0.0, 0.0,
s.z, c.z, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0 );
color = vColor;
gl_Position = vTransform *(rx * ry * rz * vPosition);
}
Your glUniformMatrix4fv does not have sufficient number of arguments. The function signature is
glUniformMatrix4fv(GLint location, GLsizei count,
GLboolean transpose, const GLfloat *value);
See the complete API docs here:
http://www.opengl.org/sdk/docs/man4/xhtml/glUniform.xml