Access violation occurred in glfwSwapBuffers() - c++

I'm making an OpenGL program using version 4.6, but when I wrote the texture code and ran the program, the following error occurred in glfwSwapBuffers():
Exception thrown at 0x00007FFCCD631970 (nvoglv64.dll) in Project1.exe: 0xC0000005: Access violation reading location 0x0000000000000000.
Here's my code :
#include"shader.h"
#include"texture.h"
#include<glad/glad.h>
#include<GLFW/glfw3.h>
#include<iostream>
int main(){
if (glfwInit() == GLFW_FALSE) {
std::cout << "Failed to initialize GLFW" << std::endl;
return -1;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(1280, 800, "What a TD", nullptr, nullptr);
if (window == nullptr) {
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if (gladLoadGL() != 1) {
std::cout << "Failed to load GLAD" << std::endl;
return -1;
}
glViewport(0, 0, 1280, 800);
GLfloat vertices[] = {
-0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f
};
GLuint indices[] = {
0, 1, 2,
2, 3, 0
};
GLuint vbo, vao, ebo;
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glGenBuffers(1, &ebo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(6 * sizeof(GLfloat)));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
texture tex0("planks.png", 0);
shader Shader("default.vs", "default.fs");
//main loop
while (!glfwWindowShouldClose(window))
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
Shader.use();
tex0.active();
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, sizeof(indices) / sizeof(GLuint), GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window); // Access violation
glfwPollEvents();
}
...
}
vertex shader :
#version 460 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;
out vec3 Color;
out vec2 texCoord;
void main() {
gl_Position = vec4(aPos, 1.0f);
Color = aColor;
texCoord = aTexCoord;
}
fragment shader :
#version 460 core
in vec3 Color;
in vec2 texCoord;
out vec4 fragColor;
uniform sampler2D tex0;
void main() {
fragColor = texture(tex0, texCoord);
}
texture.h :
#ifndef GL_TEXTURE_H
#define GL_TEXTURE_H
#include<glad/glad.h>
#include<GLFW/glfw3.h>
#include<stb/stb_image.h> //STB_IMAGE_IMPLEMENTATION defined in other file
#include<iostream>
class texture {
private:
GLuint ID;
GLuint unit;
public:
texture(const char* image, GLuint unit) {
stbi_set_flip_vertically_on_load(true);
this->unit = unit;
glGenTextures(1, &ID);
glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(GL_TEXTURE_2D, ID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
int width, height, channels;
unsigned char* data = stbi_load(image, &width, &height, &channels, 0);
if (data) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
}
else {
std::cout << image << " : " << "Failed to load image" << std::endl;
}
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(data);
glBindTexture(GL_TEXTURE_2D, 0);
}
void active() {
glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(GL_TEXTURE_2D, ID);
}
};
#endif
How can I fix this problem?

The Index Buffer (ELEMENT_ARRAY_BUFFER) binding is stored within the Vertex Array Object. When glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO) is called the element buffer object ID is stored in the currently bound Vertex Array Object.
Calling glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); when the VAO is bound breaks that binding and the index buffer is no longer bound to the VAO. Remove this line of code, you don't need it at all.
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
Unlike to the Index Buffer, the Vertex Buffer binding (ARRAY_BUFFER) is a global state.
Each attribute which is stated in the VAOs state vector may refer to a different ARRAY_BUFFER. When glVertexAttribPointer is called the buffer which is currently bound to the target ARRAY_BUFFER, is associated to the specified attribute index and the ID of the object is stored in the state vector of the currently bound VAO. Therefore there is no problem calling glBindBuffer(GL_ARRAY_BUFFER, 0);

Related

OepnGL sampling multitpe textures returns same texture color

main.cpp
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include <glad/glad.h>
#include <fstream>
#include <iostream>
#include <string>
#include <stdio.h>
#include <SOIL/SOIL.h>
typedef struct vertex{
float x; float y; float z;
float texX; float texY;
float texIndex;
} vertex;
void readTextFile(const char* path, std::string* dst);
int main(){
std::cout << 3 << std::endl;
GLFWwindow* window;
if(!glfwInit())
return -1;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(640, 480, "Geometry Shader Bathing with Texture Atlas", NULL, NULL);
if(!window){
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
gladLoadGL();
glfwSwapInterval(1);
glFrontFace(GL_CW);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//create and set vertex buffer
vertex vertices[] = {
-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
0.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
-1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
};
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
//create vertex shader
std::string* shaderSource = new std::string();
readTextFile("shader/vertexShader.glsl", shaderSource);
const char* vertexShaderSourcePtr = shaderSource->c_str();
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSourcePtr, NULL);
glCompileShader(vertexShader);
GLint status;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
if(status == GL_FALSE){
char buffer[512];
glGetShaderInfoLog(vertexShader, 512, NULL, buffer);
std::cout << "vertexShader FAIL : " << std::endl <<
shaderSource <<std::endl
<< buffer << std::endl;
}else{
std::cout << "vertexShader compile success!" << std::endl;
}
//create fragment shader
readTextFile("shader/fragmentShader.glsl", shaderSource);
const char* fragmentShaderSourcePtr = shaderSource->c_str();
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSourcePtr, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status);
if(status == GL_FALSE){
char buffer[512];
glGetShaderInfoLog(fragmentShader, 512, NULL, buffer);
std::cout << "fragmentShader FAIL : " << std::endl <<
shaderSource <<std::endl
<< buffer << std::endl;
}else{
std::cout << "fragmentShader compile success!" << std::endl;
}
delete shaderSource;
//create and set program
GLint program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glBindAttribLocation(program, 0, "inPos");
glBindAttribLocation(program, 1, "inTex");
glBindAttribLocation(program, 2, "inTexIndex");
glLinkProgram(program);
//set frameBuffer(renderTarget) index and fragmentShader output name
glBindFragDataLocation(program, 0, "outColor");
glUseProgram(program);
//create and set texture
int width = 384;
int height = 384;
unsigned char* textureRawData0 = SOIL_load_image("resource/character/test0.png", &width, &height, 0, SOIL_LOAD_RGBA);
unsigned char* textureRawData1 = SOIL_load_image("resource/character/test1.png", &width, &height, 0, SOIL_LOAD_RGBA);
glUniform1i(glGetUniformLocation(program, "texture0"), 0);
glUniform1i(glGetUniformLocation(program, "texture1"), 1);
GLuint texture1;
glGenTextures(1, &texture1);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureRawData0);
SOIL_free_image_data(textureRawData0);
std:: cout << "texture0: " << glGetUniformLocation(program, "texture0") << std::endl;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
GLuint texture2;
glGenTextures(1, &texture2);
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, texture2);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureRawData1);
SOIL_free_image_data(textureRawData1);
std:: cout << "texture1: " << glGetUniformLocation(program, "texture1") << std::endl;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//input layout : vertex Attribute
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glLinkProgram(program);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), 0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vertex), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(vertex), (void*)(5 * sizeof(float)));
while(!glfwWindowShouldClose(window)){
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 12);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
void readTextFile(const char* path, std::string* dst){
std::ifstream f;
f.open(path);
if(f.is_open()){
std::string buff;
dst->clear();
while(!f.eof()){
std::getline(f, buff);
dst->append(buff);
dst->push_back('\n');
}
dst->push_back('\0');
f.close();
}else{
std::cout << "파일 열기 실패 : " << *dst << std::endl;
}
}
ps
#version 330 core
in vec2 outTex;
in float outTexIndex;
out vec4 outColor;
uniform sampler2D texture0;
uniform sampler2D texture1;
void main(){
if(outTexIndex == 0.0f){
outColor = texture(texture0, outTex);
}
else if(outTexIndex == 1.0f){
outColor = texture(texture1, outTex) + vec4(0.5f, 0.5f, 0.5f, 1.0f);
}
}
The input layout(vertex attribute) works fine.
TexIndex is transferred correctly. 1.0f and 0.0f
But the problem is
//fragment shader
texture(texture0, outTex);
texture(texture1, outTex);
both returns same texture color but it is actually different texture from test1.png and test2.png. what is the problem with my code?
++
I tried below fragment shader following the answer of #Rabbid76
#version 330 core
in vec2 outTex;
in float outTexIndex;
out vec4 outColor;
uniform sampler2D texture0;
uniform sampler2D texture1;
void main()
{
vec4 c1 = texture(texture0, outTex) + vec4(0.5f, 0.0f, 0.0f, 1.0f);
vec4 c2 = texture(texture1, outTex) + vec4(0.0f, 0.5f, 0.0f, 1.0f);
outColor = mix(c1, c2, outTexIndex);
}
Color applied but still sampling from same the texture. looks like somehow glActiveTexture(i); doesn't work.
ps. test1.png and test2.png is completely different picture. above screenshot is test1.png
++ when I changed
glGenTexture(1, &texture0);
glGenTexture(1, &texture1);
to
glGenTexture(0, &texture0);
glGenTexture(0, &texture1);
then sampler2D texture0 and sampler2D texture1 both sample from texture1 test1.png (not form texture0 which is test0.png)
what is happening?
++
vs
#version 330
in vec3 inPos;
in vec2 inTex;
in float inTexIndex;
out vec2 outTex;
out float outTexIndex;
void main(){
outTex = inTex;
gl_position = vec4(inPos, 1.0f);
outTexIndex = inTexIndex;
}
Since the condition if(outTexIndex == 0.0f) depends on a fragment shader input, that may cause undefined behavior.
See (most recent) OpenGL Shading Language 4.60 Specification - 8.9. Texture Functions
[...] Some texture functions (non-“Lod” and non-“Grad” versions) may require implicit derivatives. Implicit derivatives are undefined within non-uniform control flow and for non-fragment shader texture fetches. [...]
respectively Non-uniform flow control.
Lookup both textures and mix the colors to solve the issue:
#version 330 core
in vec2 outTex;
in float outTexIndex;
out vec4 outColor;
uniform sampler2D texture0;
uniform sampler2D texture1;
void main()
{
vec4 c1 = texture(texture0, outTex);
vec4 c2 = texture(texture1, outTex) + vec4(0.5f, 0.5f, 0.5f, 1.0f);
outColor = mix(c1, c2, outTexIndex);
}
I thought if I have a compiled example of multiple textures that working no problem, then I can find the problem of my code changing my code line to line comparing with the example. So I found this one.
tutorial
example code
It was SDL based. So I changed initialization code and loop to glfw. And It worked fine on my environment.
Even after I changed my code's texture loading part completely same with the example, the problem wasn't solved. So it must be other part that makes the problem. Finally, I found this.
//input layout : vertex Attribute
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
//*****here!*****
//glLinkProgram(program);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), 0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vertex), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(vertex), (void*)(5 * sizeof(float)));
After I just add two characters "//", result was shown as I intended.
I'm not sure about the reason that one line of code makes problem.

How to clip texture in OpenGL?

I need to crop the image. But in opencv, it will create error because of integer domain. So I want to crop every single unit in float domain to reduce the offset error. Maybe openGL can help me, but I'm not good at it.
The image just like this ( but not this one ):
I want every black and white unit, then save them in cv::Mat.
I guess maybe shader or loop or something else can repeat to crop all block, then save them.
Now I can get one single unit. Like this:
glfwInit();//initalization
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window = glfwCreateWindow(100, 100, "LearnOpenGL", nullptr, nullptr);
if (window == nullptr)
{
cout << "Failed to create GLFW window" << endl;
glfwTerminate();
return false;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return false;
}
Shader ourShader("vertex.vs.glsl", "fragment.fs.glsl");
float unitWidth = moduleLength / (float)tex.cols;
float startP_x = 100.0f / (float)tex.cols + unitWidth * 2;
float startP_y = 104.0f / (float)tex.rows + unitWidth * 2;
float vertices[] = {
// positions // texture coords (note that we changed them to 'zoom in' on our texture image)
0.5f, 0.5f, 0.0f, startP_x + unitWidth, startP_y, // top right
0.5f, -0.5f, 0.0f, startP_x + unitWidth, startP_y + unitWidth, // bottom right
-0.5f, -0.5f, 0.0f, startP_x, startP_y + unitWidth, // bottom left
-0.5f, 0.5f, 0.0f, startP_x, startP_y // top left
};
unsigned int indices[] = {
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};
unsigned int VBO, VAO, EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// texture coord attribute
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// texture
// ---------
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
//// set the texture wrapping parameters
// set the texture wrapping parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
// set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
GLubyte* pixels;
int width = tex.cols;
int height = tex.rows;
int pixellength = width * height*tex.channels();
pixels = new GLubyte[pixellength];
memcpy(pixels, tex.data, pixellength * sizeof(unsigned char));
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, pixels);
free(pixels);
while (!glfwWindowShouldClose(window))
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// bind Texture
glBindTexture(GL_TEXTURE_2D, texture);
// draw our first triangle
ourShader.use();
// create transformations
glm::mat4 model = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first
glm::mat4 view = glm::mat4(1.0f);
glm::mat4 projection = glm::mat4(1.0f);
model = glm::rotate(model, glm::radians(0.0f), glm::vec3(1.0f, 0.0f, 0.0f));
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -1.1f));
projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
// retrieve the matrix uniform locations
unsigned int modelLoc = glGetUniformLocation(ourShader.ID, "model");
unsigned int viewLoc = glGetUniformLocation(ourShader.ID, "view");
unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "projection");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, &view[0][0]);
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(projection));
glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); // set the count to 6 since we're drawing 6 vertices now (2 triangles); not 3!
glfwPollEvents();
glfwSwapBuffers(window);
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
glfwTerminate();
return true;
vetex shader:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
out vec2 TexCoord;
void main()
{
gl_Position = projection * view * model *vec4(aPos, 1.0);
TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}
fragment shader:
#version 330 core
out vec4 FragColor;
in vec2 TexCoord;
uniform sampler2D texture1;
void main()
{
FragColor = texture(texture1, TexCoord);
}

Can't create a texture with a simple box

I'm trying to render a simple blue box to a texture, so that I can pass the texture to ImGui to render it as an image. For some reason though, I only ever get a simply white texture, and I can't figure out why. I've stripped my class down to as simple a case that I can, but I still only ever get a solid white texture, instead of a blue box that takes up most of the screen.
main.cpp
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <stdlib.h>
#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
GLFWwindow * window;
GLuint solid_texture;
GLuint loadShaders(const char * vertex_file_source, const char * fragment_file_source)
{
// Create the shaders
GLuint vertex_shader_id = glCreateShader(GL_VERTEX_SHADER);
GLuint framgent_shader_id = glCreateShader(GL_FRAGMENT_SHADER);
GLint Result = GL_FALSE;
int InfoLogLength;
glShaderSource(vertex_shader_id, 1, &vertex_file_source, NULL);
glCompileShader(vertex_shader_id);
// Check Vertex Shader
glGetShaderiv(vertex_shader_id, GL_COMPILE_STATUS, &Result);
glGetShaderiv(vertex_shader_id, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
std::vector<char> VertexShaderErrorMessage(InfoLogLength + 1);
glGetShaderInfoLog(vertex_shader_id, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
std::cerr << VertexShaderErrorMessage[0] << std::endl;
}
glShaderSource(framgent_shader_id, 1, &fragment_file_source, NULL);
glCompileShader(framgent_shader_id);
// Check Fragment Shader
glGetShaderiv(framgent_shader_id, GL_COMPILE_STATUS, &Result);
glGetShaderiv(framgent_shader_id, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
std::vector<char> FragmentShaderErrorMessage(InfoLogLength + 1);
glGetShaderInfoLog(framgent_shader_id, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
std::cerr << FragmentShaderErrorMessage[0] << std::endl;
}
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, vertex_shader_id);
glAttachShader(ProgramID, framgent_shader_id);
glLinkProgram(ProgramID);
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
std::vector<char> ProgramErrorMessage(InfoLogLength + 1);
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
std::cerr << ProgramErrorMessage[0] << std::endl;
}
glDetachShader(ProgramID, vertex_shader_id);
glDetachShader(ProgramID, framgent_shader_id);
glDeleteShader(vertex_shader_id);
glDeleteShader(framgent_shader_id);
return ProgramID;
}
void generate_solid_texture()
{
glGenTextures(1, &solid_texture);
// Solid texture
unsigned char solidTexturePixels[4];
solidTexturePixels[0] = ~0;
solidTexturePixels[1] = ~0;
solidTexturePixels[2] = ~0;
solidTexturePixels[3] = ~0;
glBindTexture(GL_TEXTURE_2D, solid_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, solidTexturePixels);
glBindTexture(GL_TEXTURE_2D, 0);
}
int main(void)
{
// Initialise GLFW
if (!glfwInit()) {
std::cerr << "Failed to initialize GLFW" << std::endl;
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Open a window and create its OpenGL context
window = glfwCreateWindow(1024, 768, "Tutorial 14 - Render To Texture", NULL, NULL);
if (window == NULL) {
fprintf(stderr,
"Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 "
"version of the tutorials.\n");
getchar();
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// We would expect width and height to be 1024 and 768
int windowWidth = 1024;
int windowHeight = 768;
// But on MacOS X with a retina screen it'll be 1024*2 and 768*2, so we get the actual framebuffer size:
glfwGetFramebufferSize(window, &windowWidth, &windowHeight);
// Initialize GLEW
glewExperimental = true; // Needed for core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
getchar();
glfwTerminate();
return -1;
}
// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
// Hide the mouse and enable unlimited mouvement
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
// Set the mouse at the center of the screen
glfwPollEvents();
glfwSetCursorPos(window, 1024 / 2, 768 / 2);
// Dark blue background
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
// Enable depth test
glEnable(GL_DEPTH_TEST);
// Setup OpenGL shaders
std::string vertex_shader_source =
R""(
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 uv;
layout (location = 2) in vec3 color;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
out vec2 frag_uv;
out vec4 frag_color;
void main()
{
frag_uv = uv;
frag_color = vec4(color, 1.0f);
gl_Position = proj_matrix * mv_matrix * vec4(position.xyz, 1);
}
)"";
std::string fragment_shader_source =
R""(
#version 330 core
uniform sampler2D Texture;
in vec2 frag_uv;
in vec4 frag_color;
layout (location = 0) out vec4 color;
void main()
{
// color = frag_color * texture(Texture, frag_uv.st);
// color = vec4((frag_color * texture(Texture, frag_uv)).xyz, 1);
color = frag_color * texture(Texture, frag_uv.st);
}
)"";
GLuint program_id = loadShaders(vertex_shader_source.c_str(), fragment_shader_source.c_str());
generate_solid_texture();
// Heatmap objects
GLuint m_vao, m_vbo, m_uvbo, m_cbo;
glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glGenBuffers(1, &m_vbo);
glGenBuffers(1, &m_uvbo);
glGenBuffers(1, &m_cbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
glBindBuffer(GL_ARRAY_BUFFER, m_uvbo);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void *)0);
glBindBuffer(GL_ARRAY_BUFFER, m_cbo);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
// Create the FBO for later
GLuint fbo, map_texture;
glGenFramebuffers(1, &fbo);
glGenTextures(1, &map_texture);
glBindVertexArray(0);
GLsizei heat_map_width = 600;
GLsizei heat_map_height = 600;
std::vector<float> map_vertices, map_vertex_uvs, map_vertex_colors;
std::vector<float> solid_uv = {0.0f, 0.0f};
std::vector<float> bl = {0, 0}, br = {1.0f, 0}, tl = {0, 1.0f}, tr = {1.0f, 1.0f};
map_vertices = {bl[0], bl[1], 1.0f, tr[0], tr[1], 1.0f, tl[0], tl[1], 1.0f,
bl[0], bl[1], 1.0f, br[0], br[1], 1.0f, tr[0], tr[1], 1.0f};
map_vertex_uvs = {solid_uv[0], solid_uv[1], solid_uv[0], solid_uv[1], solid_uv[0], solid_uv[1],
solid_uv[0], solid_uv[1], solid_uv[0], solid_uv[1], solid_uv[0], solid_uv[1]};
map_vertex_colors = {0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f};
glUseProgram(program_id);
glBindTexture(GL_TEXTURE_2D, map_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, heat_map_width, heat_map_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, map_texture, 0);
// glViewport(0, 0, heat_map_width, heat_map_height);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_DEPTH_TEST);
glEnable(GL_MULTISAMPLE);
glClearColor(0.0f, 0.0f, 0.0f, 1.00f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(m_vao);
// Vertex buffer
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, map_vertices.size() * sizeof(map_vertices[0]), map_vertices.data(), GL_STATIC_DRAW);
// UV buffer
glBindBuffer(GL_ARRAY_BUFFER, m_uvbo);
glBufferData(GL_ARRAY_BUFFER, map_vertex_uvs.size() * sizeof(map_vertex_uvs[0]), map_vertex_uvs.data(),
GL_STATIC_DRAW);
// Color buffer
glBindBuffer(GL_ARRAY_BUFFER, m_cbo);
glBufferData(GL_ARRAY_BUFFER, map_vertex_colors.size() * sizeof(map_vertex_colors[0]), map_vertex_colors.data(),
GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
static const GLfloat identity_matrix[16] = {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, 0.0f, 0.0f, 1.0f};
GLuint move_matrix_location = glGetUniformLocation(program_id, "mv_matrix");
GLuint projection_matrix_location = glGetUniformLocation(program_id, "proj_matrix");
GLuint texture_location = glGetUniformLocation(program_id, "Texture");
glUniformMatrix4fv(move_matrix_location, 1, GL_FALSE, identity_matrix);
glUniformMatrix4fv(projection_matrix_location, 1, GL_FALSE, identity_matrix);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, solid_texture);
glUniform1i(texture_location, 0);
glDrawArrays(GL_TRIANGLES, 0, map_vertices.size() / 3);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindVertexArray(0);
// Framebuffer to texture
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Always check that our framebuffer is ok
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
return false;
// The fullscreen quad's FBO
static const GLfloat g_quad_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
};
static const GLfloat g_quad_vertex_uv_data[] = {
-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f,
};
static const GLfloat g_quad_vertex_color_data[] = {
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
};
GLuint quad_vao;
glGenVertexArrays(1, &quad_vao);
glBindVertexArray(quad_vao);
GLuint quad_vertexbuffer;
glGenBuffers(1, &quad_vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_quad_vertex_buffer_data), g_quad_vertex_buffer_data, GL_STATIC_DRAW);
GLuint quad_uvbuffer;
glGenBuffers(1, &quad_uvbuffer);
glBindBuffer(GL_ARRAY_BUFFER, quad_uvbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_quad_vertex_uv_data), g_quad_vertex_uv_data, GL_STATIC_DRAW);
GLuint quad_colorbuffer;
glGenBuffers(1, &quad_colorbuffer);
glBindBuffer(GL_ARRAY_BUFFER, quad_colorbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_quad_vertex_color_data), g_quad_vertex_color_data, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
glBindBuffer(GL_ARRAY_BUFFER, quad_uvbuffer);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void *)0);
glBindBuffer(GL_ARRAY_BUFFER, quad_colorbuffer);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
glBindVertexArray(0);
do {
// Render to our framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(
0, 0, windowWidth,
windowHeight); // Render on the whole framebuffer, complete from the lower left corner to the upper right
// Clear the screen
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Use our shader
glUseProgram(program_id);
// Render to the screen
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Render on the whole framebuffer, complete from the lower left corner to the upper right
glViewport(0, 0, windowWidth, windowHeight);
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Use our shader
glUseProgram(program_id);
// Bind our texture in Texture Unit 0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, map_texture);
// Set our "renderedTexture" sampler to use Texture Unit 0
glUniform1i(texture_location, 0);
glBindVertexArray(quad_vao);
// Draw the triangles !
glDrawArrays(GL_TRIANGLES, 0, 6); // 2*3 indices starting at 0 -> 2 triangles
glBindVertexArray(0);
glDisableVertexAttribArray(0);
// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
} // Check if the ESC key was pressed or the window was closed
while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0);
// Close OpenGL window and terminate GLFW
glfwTerminate();
return 0;
}
I am fairly certain the issue is not with the vertex or fragment shaders, because I use them in another renderer class and that one works fine. Please let me know if I can provide anything else that would be of use.
Major Edit: I've created a minimal reproducible example of my issue.
Edit2: I believe I have updated it for the better, but now showing a black screen instead of a white one. I ran the generate_solid_texture function, enabled the verex atttrib arrays for the quad_vao, and set the framebuffer to default in the main loop.

Unable to get 3D view of rectangle in OpenGL

I am following this tutorial.
https://learnopengl.com/#!Getting-started/Coordinate-Systems - subtopic going 3D section i am not able to get the output only blank screen.
Here is my code:
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include "shaders.h"
#include "camera.h"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
GLFWwindow* window;
GLuint VBO, VAO,EBO;
unsigned int texture;
const unsigned int screenwidth = 800;
const unsigned int screenheight = 600;
float vertices[] =
{
0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f
};
unsigned int indices[] =
{
0, 1, 3,
1, 2, 3
};
void glfwinitializer()
{
glfwInit();
window = glfwCreateWindow(screenwidth, screenheight, "Question 2 : Camera Space", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
}
glEnable(GL_DEPTH_TEST);
}
void initializeVertex()
{
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void initializeTexture()
{
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
int width, height, nrChannels;
unsigned char *data = stbi_load("text.jpg", &width, &height, &nrChannels, 0);
if (data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);
}
int main()
{
glfwinitializer();
Shader ourShader("vertexshader.vs", "fragmentshader.fs");
initializeVertex();
initializeTexture();
glm::mat4 projection(1);
projection = glm::perspective(glm::radians(45.0f), (float)screenwidth / (float)screenheight, 0.1f, 100.0f);
ourShader.setMat4("projection", projection);
while (!glfwWindowShouldClose(window))
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, texture);
ourShader.use();
glm::mat4 model(1);
model = glm::rotate(model, glm::radians(-55.f), glm::vec3(1.0f, 0.0f, 0.0f));
ourShader.setMat4("model", model);
glm::mat4 view(1);
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
ourShader.setMat4("view", view);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
glfwTerminate();
return 0;
}
My vertex shader is :
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
out vec2 TexCoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection*view*model*vec4(aPos, 1.0);
TexCoord = vec2(aTexCoord.x,aTexCoord.y);
}
Trying to implement this code. I am getting blank output.
Output Image Here : No Rectangle
If I comment the three mode, view and projection matrix and remove from vertex shader file. . I am able to see the rectangle on the screen.
Output Image Here: Rectangle
I have one more question
glm::mat4 model(1);
glm::mat4 view(1);
glm::mat4 projection(1);
contains only value 1. When I am trying to comment following lines
//model = glm::rotate(model, glm::radians(-55.f), glm::vec3(1.0f, 0.0f, 0.0f));
//view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
//projection = glm::perspective(glm::radians(45.0f), (float)screenwidth / (float)screenheight, 0.1f, 100.0f);
and run the program without changing
gl_position = projection*view*model*vec4(aPos, 1.0);
I am getting blank screen
glUniformMatrix4fv specify the value of a uniform variable for the current program object.
This means glUseProgram has to be done before
glUniformMatrix4fv.
But you call
ourShader.setMat4("projection", projection);
before
ourShader.use();
so the uniform variable mat4 projection; is never set.
Change youre code somehow like this:
ourShader.use();
ourShader.setMat4("projection", projection);
I general your code is fine, except that you should use a minifying function for mipmaps:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

Why won't my OpenGL texture display correctly?

I'm using GLFW and GLEW to initialize a window, and SOIL to load image data for a texture. I'm trying (and failing) to load a texture to display on a simple square in the middle of the screen.
Here's the code:
GLuint VAO, VBO, EBO, texture, shaderProgram;
GLFWWindow* window;
const char* vertexShaderSource = //Shown later
const char* fragmentShaderSource = //Shown later
void init()
{
glfwInit();
window = glfwCreateWindow(320, 288, "GameBozo", nullptr, nullptr);
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
glewInit()
glViewport(0, 0, 320, 288);
GLfloat vertices[] = {
// Positions // Colors // Texture Coords
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // Top Right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Bottom Right
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Bottom Left
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // Top Left
};
GLuint indices[] = {
0, 1, 3, // First Triangle
1, 2, 3 // Second Triangle
};
//Generate vertex arrays and buffers
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
//Shaders
GLuint vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
GLuint fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
// Position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
// Color attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
// TexCoord attribute
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
glEnableVertexAttribArray(2);
// Load and create a texture
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
int width, height;
GLubyte* image = SOIL_load_image("path\to\image.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);
}
And then the main loop:
void main()
{
glfwPollEvents();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glBindTexture(GL_TEXTURE_2D, texture);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glfwSwapBuffers(window);
}
And finally, the vertex shader:
#version 330
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
layout (location = 2) in vec2 texCoord;
out vec3 ourColor;
out vec2 TexCoord;
void main()
{
gl_Position = vec4(position, 1.0f);
ourColor = color;
TexCoord = texCoord;
}
And the fragment shader:
#version 330
in vec3 ourColor;
in vec2 TexCoord;
out vec4 color;
uniform sampler2D ourTexture;
void main()
{
color = texture(ourTexture, TexCoord) * vec4(ourColor, 1.0);
}
I don't know what I'm doing wrong... the square will just show up white.