Rendering two overlapping 2D objects with 2 shaders - c++

I want to render two triangles in blue and a "windmill" in red. To do this I have created 2 shaders, which are the same except for the color. The two triangles are a lot bigger than the "windmill". The problem I'm facing is that if I switch between shaders, ONLY the last object will be rendered. If I switch to using only 1 shader, both objects will be drawn, but I can barely see the "windmill" because of the same color. So my question is how to draw both objects with two shaders? (I know I can just pass a color to the fragment shader, but I don't want to do that).
Render loop:
GLint index, index2;
index = glGetUniformLocation(shaders[LINE], "projectionMatrix");
index2 = glGetUniformLocation(shaders[TRIANGLE], "projectionMatrix");
glUniformMatrix3fv(index, 1, true, value_ptr(projectionMatrix));
glUniformMatrix3fv(index2, 1, true, value_ptr(projectionMatrix));
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaders[TRIANGLE]);
glBindVertexArray(vaos[TRIANGLE]);
glDrawArrays(GL_TRIANGLES, 0, tbufindex/sizeof(glm::vec3));
glUseProgram(shaders[LINE]); // If I comment out this line both objects will be drawn
glBindVertexArray(vaos[LINE]);
glDrawArrays(GL_LINE_STRIP, 0, sizeof(vertices_position)/sizeof(glm::vec3));
Line/Triangle.vert:
#version 450
layout (location = 0) in vec3 vPosition;
uniform mat3 projectionMatrix;
void main()
{
vec3 tmp = projectionMatrix*vPosition;
gl_Position = vec4(tmp, 1.0f);
}
Line/triangle.frag:
#version 450
in vec4 gl_FragCoord;
out vec4 fColor;
void main()
{
fColor = vec4(0.0, 0.0, 1.0, 1.0);
}
Also note that I don't have GL_DEPTH_TEST enabled, I'm using 2D coordinates.
Edit positions:
triangles[2] = { { vec3(-0.90f, -0.90f, 1.0f), vec3(0.85f, -0.90f, 1.0f), vec3(-0.90f, 0.85f, 1.0f) },
{ vec3(0.90f, -0.85f, 1.0f), vec3(0.90f, 0.90f, 1.0f), vec3(-0.85f, 0.90f, 1.0f) } };
lines[39] = {
0.0f, 0.0f, 1.0f,
0.5f, 0.0f, 1.0f,
0.5f, 0.5f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.5f, 1.0f,
-0.5f, 0.5f, 1.0f,
0.0f, 0.0f, 1.0f,
-0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, -0.5f, 1.0f,
0.5f, -0.5f, 1.0f,
0.0f, 0.0f, 1.0f
};

glUniform..() must be called after binding the program (source). So the following should work:
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaders[TRIANGLE]);
glUniformMatrix3fv(index2, 1, true, value_ptr(projectionMatrix));
glBindVertexArray(vaos[TRIANGLE]);
glDrawArrays(GL_TRIANGLES, 0, tbufindex/sizeof(glm::vec3));
glUseProgram(shaders[LINE]); // If I comment out this line both objects will be drawn
glUniformMatrix3fv(index, 1, true, value_ptr(projectionMatrix));
glBindVertexArray(vaos[LINE]);
glDrawArrays(GL_LINE_STRIP, 0, sizeof(vertices_position)/sizeof(glm::vec3));

Related

OpenGL - How to properly add lighting to a scene using the Blinn-Phong shading model?

Recently, I have been trying to add lighting to a simple OpenGL scene using the Blinn-Phong shading model as described in this website.
I tried to follow the tutorial as closely as possible. However, the lighting seems off, especially on the side faces of the cube as the light source begins to move across the front.
I believe it would have something to do with the positions of the Normals not being in the right place due to rotation on the model matrix or having done something wrong in the lighting shader, however, I am not sure whether either of those is really the cause.
Here is the source code, by the way:
#include <glad/glad.h>
#include <SFML/Graphics.hpp>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
#include <cstdlib>
#include <cmath>
// Vertex shader for the light source cube
const std::string source_vert_shader = R"(
#version 330 core
layout (location = 0) in vec3 vertPos;
uniform mat4 proj, view, model;
void main() {
gl_Position = proj * view * model * vec4(vertPos, 1);
}
)";
// Fragment shader for the light source cube
const std::string source_frag_shader = R"(
#version 330 core
out vec4 FragColor;
void main() {
FragColor = vec4(1);
}
)";
// Vertex shader for the cube
const std::string cube_vert_shader = R"(
#version 330 core
layout (location = 0) in vec3 vertPos;
layout (location = 1) in vec3 vertNorm;
uniform mat4 proj, view, model;
out vec3 fragPos;
out vec3 interNorm;
void main() {
fragPos = vec3(model * vec4(vertPos, 1));
gl_Position = proj * view * vec4(fragPos, 1);
interNorm = mat3(transpose(inverse(model))) * vertNorm;
}
)";
// Fragment shader for the cube
const std::string cube_frag_shader = R"(
#version 330 core
in vec3 fragPos;
in vec3 interNorm;
out vec4 FragColor;
uniform vec3 viewPos;
uniform vec3 lightPos;
uniform vec3 objectColor;
const float pi = 3.14159265;
const float shininess = 16;
void main() {
vec3 normal = normalize(interNorm);
vec3 lightDir = normalize(lightPos - fragPos);
float dist = length(lightPos - fragPos);
float attenuation = 1 / (dist * dist);
// Ambient light effect
const float ambientStrength = 0.05;
vec3 ambient = ambientStrength * objectColor;
// Diffuse light effect
float diff = max(dot(normal, lightDir), 0);
vec3 diffuse = attenuation * diff * objectColor;
// Specular light effect
vec3 specular = vec3(0);
if (diff != 0) {
const float energy_conservation = (8 + shininess) / (8 * pi);
vec3 viewDir = normalize(viewPos - fragPos);
vec3 halfwayDir = normalize(lightDir + viewDir);
float spec = energy_conservation * pow(max(dot(normal, halfwayDir), 0), shininess);
specular = attenuation * spec * vec3(0.3);
}
const float gamma = 2.2;
// Apply the different lighting techniques of the Phong shading model and finally apply gamma correction
FragColor = vec4(pow(ambient + diffuse + specular, vec3(1 / gamma)), 1);
}
)";
int main() {
// Initialize the window
sf::RenderWindow window(
sf::VideoMode(1365, 768), "Lighting", sf::Style::Default,
sf::ContextSettings(24, 8, 4, 3, 3, sf::ContextSettings::Core, true));
// Initialize OpenGL functions
gladLoadGLLoader(reinterpret_cast<GLADloadproc>(sf::Context::getFunction));
// Specify the viewport of the scene
glViewport(0, 0, window.getSize().x, window.getSize().y);
// Enable depth testing
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
// Enable blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Load the shaders into the application
sf::Shader shader, source_shader;
(void)shader.loadFromMemory(cube_vert_shader, cube_frag_shader);
(void)source_shader.loadFromMemory(source_vert_shader, source_frag_shader);
// Define the vertices of the cube and the light source cube
float vertices[] = {
// Vertices Normals
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f
};
// Attach the vertices in the vertices array to the VAO and the VBO
GLuint vao, vbo;
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), nullptr);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), reinterpret_cast<void*>(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
// The same VBO can be used to render the light source cube
GLuint source_vao;
glGenVertexArrays(1, &source_vao);
glBindVertexArray(source_vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), nullptr);
glEnableVertexAttribArray(0);
// Projection matrix
auto proj = glm::perspective(glm::radians(45.0f), static_cast<GLfloat>(window.getSize().x) / window.getSize().y, 0.1f, 100.0f);
glm::vec3 view_pos(0.0f, 0.0f, -5.0f);
// View/camera matrix
glm::mat4 view(1.0f);
view = glm::translate(view, view_pos);
view = glm::rotate(view, glm::radians(45.0f), glm::vec3(1.0f, 1.0f, 1.0f));
// Model matrix
glm::mat4 model(1.0f);
//model = glm::rotate(model, glm::radians(45.0f), glm::vec3(1.0f, 1.0f, 0.0f));
// For the cube in the center
shader.setUniform("proj", sf::Glsl::Mat4(glm::value_ptr(proj)));
shader.setUniform("view", sf::Glsl::Mat4(glm::value_ptr(view)));
shader.setUniform("model", sf::Glsl::Mat4(glm::value_ptr(model)));
shader.setUniform("viewPos", sf::Glsl::Vec3(view_pos.x, view_pos.y, view_pos.z));
shader.setUniform("objectColor", sf::Glsl::Vec3(1.0f, 0.3f, 1.0f));
// For the light source cube
source_shader.setUniform("proj", sf::Glsl::Mat4(glm::value_ptr(proj)));
source_shader.setUniform("view", sf::Glsl::Mat4(glm::value_ptr(view)));
sf::Clock clock;
sf::Event evt{};
while (window.isOpen()) {
while (window.pollEvent(evt)) {
if (evt.type == sf::Event::Closed) {
// When window is closed, destroy the VAO and the VBO
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
window.close();
}
if (evt.type == sf::Event::Resized)
// Update the viewport as the window is resized
glViewport(0, 0, evt.size.width, evt.size.height);
}
// Clear the screen with a color
glClearColor(0.8f, 0.2f, 0.6f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Calculate an angular factor based on the elapsed time
auto const angular_factor = glm::radians(45.0f) * clock.getElapsedTime().asSeconds();
sf::Shader::bind(&shader);
// Makes the light source move in circles around the cube in the center
glm::vec3 light_pos(
6.0f * std::sin(angular_factor),
0.0f,
6.0f * std::cos(angular_factor)
);
shader.setUniform("lightPos", sf::Glsl::Vec3(light_pos.x, light_pos.y, light_pos.z));
// Draw the cube
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 36);
sf::Shader::bind(&source_shader);
model = glm::identity<glm::mat4>();
model = glm::scale(model, glm::vec3(0.3f, 0.3f, 0.3f));
model = glm::translate(model, light_pos);
source_shader.setUniform("model", sf::Glsl::Mat4(glm::value_ptr(model)));
// Draw the light source cube
glBindVertexArray(source_vao);
glDrawArrays(GL_TRIANGLES, 0, 36);
sf::Shader::bind(nullptr);
// Swap the window's buffers
window.display();
}
}

modern opengl textured pyramid

I think am missing something when drawing the textured pyramid. I can't get it to work properly since I am not good with 3d modern OpenGL. Somehow, I managed to draw a cube but seems am going wrong with the pyramid. I want the four sides to have 0.5(top), 0.0(left), 1,0 (right). and the bottom to be 0,1 (top left), 1,1 (top right), 0,0 (bottom left) and 1,0 (bottom right). I need these coordinates since am only getting flunky images with my coordinate. Any help would be appreciated.
here is my code with the vertices of a cube that I had created earlier and was running well.
/*Header Inclusions*/
#include <iostream>
#include <GL/Glew.h>
#include <GL/freeglut.h>
// GLM Math inclusions
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include<glm/gtc/type_ptr.hpp>
//include soil
#include "SOIL2/SOIL2.h"
using namespace std; // Uses the standard namespace
#define WINDOW_TITLE "Modern OpenGL" // Macro for window title
//Vertex and fragment shader
#ifndef GLSL
#define GLSL(Version, source) "#version " #Version "\n" #source
#endif
// Variables for window width and height
GLint ShaderProgram, WindowWidth = 800, WindowHeight = 600;
GLuint VBO, VAO, texture;
GLfloat degrees = glm::radians(-45.0f);
/* User-defined Function prototypes to:*/
void UResizeWindow(int,int);
void URenderGraphics(void);
void UCreateShader(void);
void UCreateBuffers(void);
void UGenerateTexture(void);
/*Vertex shader source code*/
const GLchar * vertexShaderSource = GLSL(330,
layout(location = 0) in vec3 position;
layout(location = 2) in vec2 textureCoordinate;
out vec2 mobileTextureCoordinate; //declare a vec 4 variable
//Global variables for the transform matrices
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main(){
gl_Position = projection * view * model * vec4(position, 1.0f);//transform vertices
mobileTextureCoordinate = vec2(textureCoordinate.x, 1.0f - textureCoordinate.y);
}
);
/*Fragment shader program source code*/
const GLchar * fragmentShaderSource = GLSL(330,
in vec2 mobileTextureCoordinate;
out vec4 gpuTexture;//out vertex_Color;
uniform sampler2D uTexture;
void main(){
gpuTexture = texture(uTexture, mobileTextureCoordinate);
}
);
//main program
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(WindowWidth, WindowHeight);
glutCreateWindow(WINDOW_TITLE);
glutReshapeFunc(UResizeWindow);
glewExperimental = GL_TRUE;
if (glewInit()!= GLEW_OK)
{
std::cout << "Failed to initialize GLEW" << std::endl;
return -1;
}
UCreateShader();
UCreateBuffers();
UGenerateTexture();
// Use the Shader program
glUseProgram(ShaderProgram);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color
glutDisplayFunc(URenderGraphics);
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
glutMainLoop();
// Destroys Buffer objects once used
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
return 0;
}
/* Resizes the window*/
void UResizeWindow(int w, int h)
{
WindowWidth = w;
WindowHeight = h;
glViewport(0, 0, WindowWidth, WindowHeight);
}
/* Renders graphics */
void URenderGraphics(void)
{
glEnable(GL_DEPTH_TEST); // Enable z-depth
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clears the screen
glBindVertexArray(VAO); // Activate the Vertex Array Object before rendering and transforming them
// Transforms the object
glm::mat4 model;
model = glm::translate(model, glm::vec3(0.0, 0.0f, 0.0f)); // Place the object at the center of the 7i,p9rA
model = glm::rotate(model, degrees, glm::vec3(0.0, 1.0f, 0.0f)); // Rotate the object 45 degrees on the XYZ
model = glm::scale(model, glm::vec3(2.0f, 2.0f, 2.0f)); // Increase the object size by a scale of 2
// Transforms the camera
glm::mat4 view;
view = glm::translate(view, glm::vec3(0.0f,0.0f,-5.0f)); //Moves the world 0.5 units on X and -5 units in Z
// Creates a perspective projection
glm::mat4 projection;
projection = glm::perspective(45.0f, (GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f);
// Retrieves and passes transform matrices to the Shader program
GLint modelLoc = glGetUniformLocation(ShaderProgram, "model");
GLint viewLoc = glGetUniformLocation(ShaderProgram, "view");
GLint projLoc = glGetUniformLocation(ShaderProgram, "projection");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
glutPostRedisplay();
glBindTexture(GL_TEXTURE_2D, texture);
// Draws the triangles
glDrawArrays(GL_TRIANGLES,0, 36);
glBindVertexArray(0); // Deactivate the Vertex Array Object
glutSwapBuffers(); // Flips the the back buffer with the front buffer every frame. Similar to GL FLush
}
/*Creates the Shader program*/
void UCreateShader()
{
// Vertex shader
GLint vertexShader = glCreateShader(GL_VERTEX_SHADER); // Creates the Vertex Shader
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); // Attaches the Vertex Shader to the source code
glCompileShader(vertexShader); // Compiles the Vertex Shader
// Fragment Shader
GLint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); // Creates the Fragment Shader
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);// Attaches the Fragment Shader to the source code
glCompileShader(fragmentShader); // Compiles the Fragment Shader
// Shader program
ShaderProgram = glCreateProgram(); // Creates the Shader program and returns an id
glAttachShader(ShaderProgram, vertexShader); // Attach Vertex Shader to the Shader program
glAttachShader(ShaderProgram, fragmentShader);; // Attach Fragment Shader to the Shader program
glLinkProgram(ShaderProgram); //Link Vertex and Fragment shader, to Shader program
// Delete the Vertex and Fragment shaders once linked
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
/*creates the buffer and array object*/
void UCreateBuffers()
{
//position and color data
GLfloat vertices[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
};
//Generate buffer id,
glGenVertexArrays(1, &VAO);
glGenBuffers(1,&VBO);
// Activate the Vertex Array Object before binding and setting any VB0s and Vertex Attribute Pointers.
glBindVertexArray(VAO);
// Activate the VBO
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //Copy vertices to VBO
// Set attribute pointer 0 to hold Position data
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0); // Enables vertex attribute
// Set attribute pointer 2 to hold Color data
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(2); // Enables vertex attribute
glBindVertexArray(0); // Deactivates the VAC, which is good practice
}
/*Generate and load the texture*/
void UGenerateTexture(){
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
int width,height;
unsigned char* image = SOIL_load_image("snhu.jpg", &width, &height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(image);
glBindTexture(GL_TEXTURE_2D, 0);
}
I recommend to define a structure type for the attribute tuples:
struct TAttributeTuple
{
glm::vec3 v;
glm::vec2 uv;
};
Define the 5 corner points of the pyramid:
(Your explanation of the points is a bit unclear, so I am not sure if the points are according to your specification. Possibly you've modify them.)
glm::vec3 top( 0.5f, 0.5f, 0.5f );
glm::vec3 p01( -0.1f, 0.0f, 1.0f );
glm::vec3 p11( 1.1f, 0.0f, 1.0f );
glm::vec3 p00( 0.0f, 0.0f, 0.0f );
glm::vec3 p10( 1.0f, 0.0f, 0.0f );
Setup the array of vertex attributes:
TAttributeTuple vertices[]
{
{ p00, glm::vec2(0.0f, 0.0f) },
{ p10, glm::vec2(1.0f, 0.0f) },
{ p11, glm::vec2(1.0f, 1.0f) },
{ p00, glm::vec2(0.0f, 0.0f) },
{ p11, glm::vec2(1.0f, 1.0f) },
{ p01, glm::vec2(0.0f, 1.0f) },
{ p00, glm::vec2(0.0f, 0.0f) },
{ p10, glm::vec2(1.0f, 0.0f) },
{ top, glm::vec2(0.5f, 1.0f) },
{ p10, glm::vec2(0.0f, 0.0f) },
{ p11, glm::vec2(1.0f, 0.0f) },
{ top, glm::vec2(0.5f, 1.0f) },
{ p11, glm::vec2(0.0f, 0.0f) },
{ p01, glm::vec2(1.0f, 0.0f) },
{ top, glm::vec2(0.5f, 1.0f) },
{ p01, glm::vec2(0.0f, 0.0f) },
{ p00, glm::vec2(1.0f, 0.0f) },
{ top, glm::vec2(0.5f, 1.0f) }
};

opengl - flickering of fragments even with disabled depth test

I'm trying to render a quad with a coloured border. I'm using texture coordinates to detect whether the fragment should be considered part of border or not. If it is part of border, then render it with green colour or else with black colour.
Here are my vertices / normals / tex coordinates.
float vertices[] = {
// posistions // normals // texture coords
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
}
Here's my fragment shader
#version 330 core
in vec3 frag_pos;
in vec3 frag_nor;
in vec2 frag_tex;
out vec4 frag_color;
void main()
{
vec2 origin = vec2(0.01, 0.01);
float width = 1.0 - origin.x * 2.0;
float height = 1.0 - origin.y * 2.0;
if( (frag_tex.x >= origin.x && frag_tex.x < origin.x + width) &&
(frag_tex.y >= origin.y && frag_tex.y < origin.y + height) )
{
frag_color = vec4(0.0);
}
else
{
frag_color = vec4(0.0, 1.0, 0.0, 0.0);
}
}
And this is how I'm rendering
glDisable(GL_DEPTH_TEST);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 6);
In right, I'm drawing the same quad with another pass-through fragment shader in wireframe mode.
As you can see the left quad is flickering while moving the camera. Any ideas how to fix this.
The problem exist even with applying a 2D texture. To fix that, I used Mipmaps with these filters.
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

OpenGL - Going 3D

I have a script that I am unable to make fully 3D. So far on ortho the background shows up only. In perspective, almost nothing shows up but when I move the camera it does change color.
projection = glm::perspective(glm::radians(44.0f), static_cast<GLfloat>(Width) / static_cast<GLfloat>(Height), 0.1f, 100.0f);
projection = glm::ortho(0.0f, static_cast<GLfloat>(Width), static_cast<GLfloat>(Height), 0.0f, -1.0f, 1.0f);
See below for images:
Image 1:
3D version - Ortho
Image 2:
3D version - Ortho
Image 3:
2D version - Stable and works perfectly
Here is my code that creates and renders sprites:
#ifndef SPRITE_H
#define SPRITE_H
#include <GL/glew.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "ShaderClass.h"
#include "TextureClass.h"
class Sprite
{
public:
Shader shader;
// Set up Vertex Array Object && Vertex Buffer Object
GLuint VAO,
VBO;
// Constructor
Sprite(Shader &shader){ this->shader = shader; setBuffers(); }
// Deconstructor
~Sprite(){ glDeleteVertexArrays(1, &VAO); }
// Initializes and configures the buffers and vertex attributes
void setBuffers()
{
// Define vertices for the sprite
GLfloat vertices[] = {
// x y z u v
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 1.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
//
// OpenGL buffers
// Initialization code using Vertex Array Object (VAO) (done once (unless the object frequently changes))
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
// Copy our vertices array in a buffer for OpenGL to use
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Bind Vertex Array Object
glBindVertexArray(VAO);
//Attributes
glEnableVertexAttribArray(0); // location = 0
glVertexAttribPointer(
0, // location = 0
3, // 3 components (x, y, z)
GL_FLOAT, GL_FALSE,
5 * sizeof(GLfloat), // stride: 5 * float (x, y, z, u, v)
(GLvoid*)0); // offset: 0
glEnableVertexAttribArray(1); // location = 1
glVertexAttribPointer(
1, // location = 1
2, // 2 components (u, v)
GL_FLOAT, GL_FALSE,
5 * sizeof(GLfloat), // stride: 5 * float (x, y, z, u, v)
(GLvoid*)(3 * sizeof(GLfloat))); // offset: 3 * float (x, y, z)
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//Unbind the VAO
glBindVertexArray(0);
}
// Renders the sprite
void DrawSprite(Texture &texture, glm::vec2 position, glm::vec2 size = glm::vec2(10, 10), GLfloat rotate = 0.0f, glm::vec3 colour = glm::vec3(1.0f))
{
// Apply the shader
this->shader.Use();
// Transform the object
glm::mat4 transformObject;
transformObject = glm::translate(transformObject, glm::vec3(position, 0.0f));
transformObject = glm::translate(transformObject, glm::vec3(0.5f * size.x, 0.5f * size.y, 0.0f));
transformObject = glm::rotate(transformObject, rotate, glm::vec3(0.0f, 0.0f, 1.0f));
transformObject = glm::translate(transformObject, glm::vec3(-0.5f * size.x, -0.5f * size.y, 0.0f));
transformObject = glm::scale(transformObject, glm::vec3(size, 1.0f));
this->shader.SetVector3f("spriteColour", colour);
this->shader.SetMatrix4("transformObject", transformObject);
glActiveTexture(GL_TEXTURE0);
// Bind the appropriate texture to *this* model
texture.Bind();
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36 * 5);
glBindVertexArray(0);
}
};
#endif
These are the shaders that I am using:
Vertex shader:
#version 440 core
layout (location = 0) in vec3 Position;
layout (location = 1) in vec2 texCoord;
out vec2 TexCoords;
uniform mat4 transformObject;
uniform mat4 view;
uniform mat4 projection;
void main()
{
TexCoords = vec2(texCoord.x, texCoord.y);
gl_Position = projection * view * transformObject * vec4(Position.x, Position.y, Position.z, 1.0);
}
Fragment shader:
#version 440 core
in vec2 TexCoords;
out vec4 colour;
uniform sampler2D tex;
uniform vec3 spriteColour;
void main()
{
colour = vec4(spriteColour, 1.0) * texture(tex, TexCoords);
}

Inproper texture mapping while using QGLBuffer

I wrought basic OpenGL 2.1\ES example for supposed target platform, using Qt 4.7.1 library on Windows. Target is some kind of Linux, with Qt 4.8 max available, no glm or similar libraries. Embedded GPU supports ES 1.0 or OpenGL 2.1 only. Example is "classic" texture cube, which you might met in various OpenGL examples.. but those examples use direct calls to OpenGL functions, what isn't available to me for lack of proper headers and glew - both on development and on target platforms. Development platform is Windows 7.
Geometry
static const int vertexDataCount = 6 * 4 * 4;
static const float vertexData[vertexDataCount] = {
// Left face
-0.5f, -0.5f, -0.5f, 1.0f,//0
-0.5f, -0.5f, 0.5f, 1.0f,//1
-0.5f, 0.5f, 0.5f, 1.0f,//2
-0.5f, 0.5f, -0.5f, 1.0f,//3
// Top face
-0.5f, 0.5f, -0.5f, 1.0f, //4
-0.5f, 0.5f, 0.5f, 1.0f, //5
0.5f, 0.5f, 0.5f, 1.0f, //6
0.5f, 0.5f, -0.5f, 1.0f, //7
// Right face
0.5f, 0.5f, -0.5f, 1.0f,//8
0.5f, 0.5f, 0.5f, 1.0f,//9
0.5f, -0.5f, 0.5f, 1.0f,//10
0.5f, -0.5f, -0.5f, 1.0f,//11
// Bottom face
0.5f, -0.5f, -0.5f, 1.0f,//12
0.5f, -0.5f, 0.5f, 1.0f,//13
-0.5f, -0.5f, 0.5f, 1.0f,//14
-0.5f, -0.5f, -0.5f, 1.0f,//15
// Front face
0.5f, -0.5f, 0.5f, 1.0f,//16/
0.5f, 0.5f, 0.5f, 1.0f,//17
-0.5f, 0.5f, 0.5f, 1.0f,//18
-0.5f, -0.5f, 0.5f, 1.0f,//19
// Back face
0.5f, 0.5f, -0.5f, 1.0f,//20
0.5f, -0.5f, -0.5f, 1.0f,//21
-0.5f, -0.5f, -0.5f, 1.0f,//22
-0.5f, 0.5f, -0.5f, 1.0f //23
};
// Normal vectors
static const int normalDataCount = 6 * 4 * 3;
static const float normalData[normalDataCount] = {
// Left face
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
// Top face
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
// Right face
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
// Bottom face
0.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
// Front face
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
// Back face
0.0f, 0.0f, -1.0f,
0.0f, 0.0f, -1.0f,
0.0f, 0.0f, -1.0f,
0.0f, 0.0f, -1.0f
};
// Texure coords
static const int textureCoordDataCount = 6 * 4 * 2;
static const float textureCoordData[textureCoordDataCount] = {
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f
};
// Indices
//
// 3 indices per triangle
// 2 triangles per face
// 6 faces
static const int indexDataCount = 6 * 3 * 2;
static const unsigned int indexData[indexDataCount] = {
0, 1, 2, 0, 2, 3, // Left face
4, 5, 6, 4, 6, 7, // Top face
8, 9, 10, 8, 10, 11, // Right face
12, 14, 15, 12, 13, 14, // Bottom face
16, 17, 18, 16, 18, 19, // Front face
20, 22, 23, 20, 21, 22 // Back face
};
This is how I load texture
glEnable(GL_TEXTURE_2D);
m_texture = bindTexture(QImage("cube.png"));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
if(m_shaderProgram)
m_shaderProgram->setUniformValue("texture", 0); // texture unit 0, assuming that we used
Vertex shader
#version 120
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
attribute vec4 vertex;
attribute vec3 normal;
attribute vec2 texturecoord;
varying vec3 fragmentNormal;
varying vec2 outtexture;
void main( void )
{
// Transform the normal vector
fragmentNormal = ( modelViewMatrix * vec4( normal, 0.0 ) ).xyz;
// Calculate the clip-space coordinates
gl_Position = projectionMatrix * modelViewMatrix * vertex;
outtexture = texturecoord;
}
Fragment shader
#version 120
// in
uniform sampler2D texture;
varying vec2 outtexture;
varying vec3 fragmentNormal;
// out
// gl_FragColor
void main( void )
{
// Calculate intensity as max of 0 and dot product of the
// fragmentNormal and the eye position (0,0,1).
float intensity;
intensity = max( dot( fragmentNormal, vec3( 0.0, 0.0, 1.0 ) ), 0.15 );
gl_FragColor = intensity * texture2D(texture,outtexture); // vec4( 1.0, 0.0, 0.0, 1.0 );
}
I bind buffers this way (prepareBufferObject is little snippet function I took from Qt sample):
// Prepare the vertex, normal and index buffers
m_vertexBuffer = new QGLBuffer(QGLBuffer::VertexBuffer );
if ( !prepareBufferObject( m_vertexBuffer, QGLBuffer::StaticDraw, vertexData, sizeof(vertexData) ) )
return;
m_normalBuffer = new QGLBuffer(QGLBuffer::VertexBuffer );
if ( !prepareBufferObject( m_normalBuffer, QGLBuffer::StaticDraw, normalData, sizeof(normalData) ) )
return;
m_texBuffer = new QGLBuffer(QGLBuffer::IndexBuffer );
if ( !prepareBufferObject( m_texBuffer, QGLBuffer::StaticDraw, textureCoordData, sizeof(textureCoordData) ) )
return;
m_indexBuffer = new QGLBuffer(QGLBuffer::IndexBuffer );
if ( !prepareBufferObject( m_indexBuffer, QGLBuffer::StaticDraw, indexData, sizeof(indexData) ) )
return;
loadShaders("vertexshader120.glsl", "fragshader120.glsl");
// Enable the "vertex" attribute to bind it to our vertex buffer
m_vertexBuffer->bind();
m_shaderProgram->setAttributeBuffer( "vertex", GL_FLOAT, 0, 4 ); //xyzw
m_shaderProgram->enableAttributeArray( "vertex" );
// Enable the "normal" attribute to bind it to our texture coords buffer
m_normalBuffer->bind();
m_shaderProgram->setAttributeBuffer( "normal", GL_FLOAT, 0, 3 ); //xyz
m_shaderProgram->enableAttributeArray( "normal" );
m_texBuffer->bind();
m_shaderProgram->setAttributeBuffer( "texturecoord", GL_FLOAT, 0, 2 ); //uv
m_shaderProgram->enableAttributeArray( "texturecoord" );
// Bind the index buffer ready for drawing
m_indexBuffer->bind();
Finally , paintGL method
void GWidget::paintGL()
{
QMatrix4x4 model;
model.setToIdentity();
model.rotate(m_rotation);
QMatrix4x4 mv = m_view * model;
// MVP = projection * view * model
// uploading MVP into shader (may add code to check if MVP was update since last redraw)
m_shaderProgram->setUniformValue("modelViewMatrix",mv);
m_shaderProgram->setUniformValue("projectionMatrix",m_projection);
// set up to render the scene
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw stuff
glDrawElements( GL_TRIANGLES, // Type of primitive to draw
indexDataCount, // The number of indices in our index buffer we wish to draw
GL_UNSIGNED_INT, // The element type of the index buffer
0 ); // Offset from the start of our index buffer of where to begin
}
Everything works except texture looks misaligned and skewed -both on development and on target platforms. I checked UVs and that they correspond to proper vertices - yet it looks like order of texture coordinates is wrong. Where is error here?
For reference: source code
This is my first attempt at usage of flexible pipeline, so I could do something dumb there.
You're setting up your texture coordinate buffer as an index buffer:
m_texBuffer = new QGLBuffer(QGLBuffer::IndexBuffer );
Since it contains vertex attribute data, it should be created as:
m_texBuffer = new QGLBuffer(QGLBuffer::VertexBuffer);