OpenGL not drawing in 3D with depth buffers enabled - c++

I've spent 2 weeks trying to get OpenGL to draw a cube in 3D, but no matter what I do, it never actually drew a cube. If I enable the depth test with glEnable(DEPTH_TEST), it simply does not render anything. If I comment out that function, it renders all the vertices as if the z-values were all 0. I'm completely stuck and have no idea what i've done wrong.
Here's my main file: https://pastebin.com/D8cEcJ4g
#include "Dependencies\glew\glew.h"
#include "Dependencies\freeglut\freeglut.h"
#include "Dependencies\soil\SOIL.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include <iostream>
#include "ShaderLoader.h";
#include "Camera.h"
#define BUTTON_UP 0
#define BUTTON_DOWN 1
GLuint program;
GLuint vao, vbo, ebo;
GLuint texture, texture2;
unsigned char keyState[255];
glm::vec3 vPosTrans = glm::vec3(-0.50f, -0.50f, 0.0f);//source
glm::vec3 vPosInit = vPosTrans;
glm::vec3 vPosDest = glm::vec3(0.50f, 0.50f, 0.0f);//destination
glm::vec3 vCurrentPos = vPosTrans;
bool Dest1or2 = true;
const GLfloat WIDTH = 800.0f, HEIGHT = 600.0f;
Camera* camera;
void init(){
camera = new Camera(180.0f, WIDTH, HEIGHT, 0.0f, 100.0f);
ShaderLoader shaderLoader;
program = shaderLoader.CreateProgram("CoordSystem_Texture_QUAD.vs", "CoordSystem_Texture_QUAD.fs");
glEnable(GL_DEPTH_TEST);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// Set up vertex data (and buffer(s)) and attribute pointers
GLfloat vertices[] = {
//position //color //texture coord //Normals
-1.01f, -1.01f, -1.01f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, -1.01f, 0.0f, 1.0f, -0.0f, 0.0f, 0.0f,
1.01f, 1.01f, -1.01f, 1.0f, 0.0f, -0.0f, 1.0f, 0.0f,
1.01f, -1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
// Fill in the back face vertex data.
-1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.01f, -1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
// Fill in the top face vertex data.
-1.01f, 1.01f, -1.01f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.01f, 1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f,
1.01f, 1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
// Fill in the bottom face vertex data.
-1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.01f, -1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-1.01f, -1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
// Fill in the left face vertex data.
-1.01f, -1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.01f, 1.01f, -1.01f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
-1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
// Fill in the right face vertex data.
1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
1.01f, 1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
};
GLuint indices[] = {
// front
0, 1, 2,
0, 2, 3,
// top
4, 5, 6,
4, 6, 7,
// back
8, 9, 10,
8, 10, 11,
// bottom
12, 13, 14,
12, 14, 15,
// left
16, 17, 18,
16, 18, 19,
// right
20, 21, 22,
20, 22, 23,
};
//** VAO **
// Generate vertex arrow object
glGenVertexArrays(1, &vao);
// Bind the Vertex Array Object to openGl context
glBindVertexArray(vao);//otherwise glVertexAttribPointer
//** VBO **
// Then bind and set vertex buffer(s).
// First paramter is how many buffers we have to create
glGenBuffers(1, &vbo);
// bind VBO to binding point, here it is GL_ARRAY_BUFFER
// there are other binding points
glBindBuffer(GL_ARRAY_BUFFER, vbo);//bind to context
glBufferData(GL_ARRAY_BUFFER,
sizeof(vertices),// GPU need to know how much memory needs to be allocated
vertices,//copy data to GPU
GL_STATIC_DRAW);// How to use the buffer - buffer is created and modified once
//** EBO **
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof(indices),
indices,
GL_STATIC_DRAW);
// ** Attributes **
//** Vertex 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);
// It's always a good thing to unbind any buffer/array to prevent strange bugs
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
//** Load and bind texture 1
//--------------------------
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
//** loadImage and create texture
// Load image, create texture and generate mipmaps
int width, height;
unsigned char* image = SOIL_load_image("wall.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);
// ** Load and Bind Texture 2
//---------------------------
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
//** loadImage and create texture
// Load image, create texture and generate mipmaps
unsigned char* image2 = SOIL_load_image("awesomeface.png", &width, &height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image2);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(image2);
glBindTexture(GL_TEXTURE_2D, 0);
// Set texture wrapping to GL_REPEAT (usually basic wrapping method)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
void render(){
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw our first triangle
glUseProgram(program);
//bind
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(glGetUniformLocation(program, "Texture"), 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
glUniform1i(glGetUniformLocation(program, "Texture2"), 1);
glBindVertexArray(vao);
// Draw Elements intead of vertex array
glDrawArrays(GL_QUADS, 0, 24);
//glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glutSwapBuffers();
}
void update(){
GLfloat cameraSpeed = 0.05f;
camera->setCameraSpeed(cameraSpeed);
//currentTime uniform
GLfloat currentTime = glutGet(GLUT_ELAPSED_TIME);
currentTime = currentTime / 1000;
GLint currentTimeLocation = glGetUniformLocation(program, "currentTime");
glUniform1f(currentTimeLocation, currentTime);
//transforms
glm::mat4 transform = glm::mat4(1.0f);
glm::vec3 vScaleVec = glm::vec3(0.51f, 0.51f, 0.0f);
glm::mat4 model = glm::mat4(1.0);
if (keyState[(unsigned char)'w'] == BUTTON_DOWN) {
camera->moveForward();
std::cout << "e";
}
if (keyState[(unsigned char)'s'] == BUTTON_DOWN) {
camera->moveBack();
std::cout << "A";
}
camera->Update();
//glm::mat4 projection = glm::perspective(45.0f, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f);
glm::mat4 projection = camera->getProjectionMatrix();
glm::mat4 view = glm::lookAt(camera->getCameraPos(), camera->getCameraPos() + camera->getCameraFront(), camera->getCameraUp());
//glm::mat4 view = glm::lookAt(glm::vec3(1, 1, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1));
GLfloat radius = 3.5f;
GLfloat camX = sin(currentTime) * radius;
GLfloat camZ = cos(currentTime) * radius;
//glm::mat4 view = glm::lookAt(
// glm::vec3(camX, 0.0, camZ),
// glm::vec3(0.0, 0.0, 0.0),
// glm::vec3(0.0, 1.0, 0.0));
transform = glm::scale(transform, vScaleVec);
glm::vec3(0.65f, 0.65f, 0.65f);
//transform = glm::rotate(transform, 90.0f, glm::vec3(0.0, 0.0, 1.0));
if (vCurrentPos == vPosDest && Dest1or2 == true )
{
Dest1or2 = false;
}
else if (vCurrentPos == vPosTrans && Dest1or2 == false)
{
Dest1or2 = true;
}
if(Dest1or2)
vCurrentPos = glm::mix(vCurrentPos, vPosDest, currentTime * 0.01f);
else
vCurrentPos = glm::mix(vCurrentPos, vPosTrans, currentTime*0.01f);
//transform = glm::translate(transform, vCurrentPos);
//transform = glm::translate(transform, glm::vec3(-0.51f, -0.51f, 0.0f));
//transform = glm::rotate(transform, ((GLfloat)currentTime / 100) * 90.0f, glm::vec3(0.0f, 0.0f, 1.0f));
// RTS
GLuint transformLoc = glGetUniformLocation(program, "transform");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));
GLint modelLoc = glGetUniformLocation(program, "model");
GLint viewLoc = glGetUniformLocation(program, "view");
GLint projLoc = glGetUniformLocation(program, "projection");
// Pass them to the shaders
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(camera->getViewMatrix()));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(camera->getProjectionMatrix()));
//glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
//glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
glutPostRedisplay();
}
void keyboard(unsigned char key, int x, int y) {
keyState[key] = BUTTON_DOWN;
//printf("key pressed: %d \n", key);
}
void keyboard_up(unsigned char key, int x, int y) {
keyState[key] = BUTTON_UP;
}
int main(int argc, char **argv){
// init glut
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(300, 200);
glutInitWindowSize(800, 600);
glutCreateWindow("QUAD EBO");
//init GLEW
glewInit();
init();
//clear
glClearColor(1.0, 0.0, 0.0, 1.0);//clear red
// register callbacks
glutDisplayFunc(render);
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboard_up);
glutIdleFunc(update);
glutMainLoop();
return 0;
}
RAW Paste Data
#include "Dependencies\glew\glew.h"
#include "Dependencies\freeglut\freeglut.h"
#include "Dependencies\soil\SOIL.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include <iostream>
#include "ShaderLoader.h";
#include "Camera.h"
#define BUTTON_UP 0
#define BUTTON_DOWN 1
GLuint program;
GLuint vao, vbo, ebo;
GLuint texture, texture2;
unsigned char keyState[255];
glm::vec3 vPosTrans = glm::vec3(-0.50f, -0.50f, 0.0f);//source
glm::vec3 vPosInit = vPosTrans;
glm::vec3 vPosDest = glm::vec3(0.50f, 0.50f, 0.0f);//destination
glm::vec3 vCurrentPos = vPosTrans;
bool Dest1or2 = true;
const GLfloat WIDTH = 800.0f, HEIGHT = 600.0f;
Camera* camera;
void init(){
camera = new Camera(180.0f, WIDTH, HEIGHT, 0.0f, 100.0f);
ShaderLoader shaderLoader;
program = shaderLoader.CreateProgram("CoordSystem_Texture_QUAD.vs", "CoordSystem_Texture_QUAD.fs");
glEnable(GL_DEPTH_TEST);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// Set up vertex data (and buffer(s)) and attribute pointers
GLfloat vertices[] = {
//position //color //texture coord //Normals
-1.01f, -1.01f, -1.01f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, -1.01f, 0.0f, 1.0f, -0.0f, 0.0f, 0.0f,
1.01f, 1.01f, -1.01f, 1.0f, 0.0f, -0.0f, 1.0f, 0.0f,
1.01f, -1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
// Fill in the back face vertex data.
-1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.01f, -1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
// Fill in the top face vertex data.
-1.01f, 1.01f, -1.01f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.01f, 1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f,
1.01f, 1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
// Fill in the bottom face vertex data.
-1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.01f, -1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-1.01f, -1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
// Fill in the left face vertex data.
-1.01f, -1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.01f, 1.01f, -1.01f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
-1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
// Fill in the right face vertex data.
1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
1.01f, 1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
};
GLuint indices[] = {
// front
0, 1, 2,
0, 2, 3,
// top
4, 5, 6,
4, 6, 7,
// back
8, 9, 10,
8, 10, 11,
// bottom
12, 13, 14,
12, 14, 15,
// left
16, 17, 18,
16, 18, 19,
// right
20, 21, 22,
20, 22, 23,
};
//** VAO **
// Generate vertex arrow object
glGenVertexArrays(1, &vao);
// Bind the Vertex Array Object to openGl context
glBindVertexArray(vao);//otherwise glVertexAttribPointer
//** VBO **
// Then bind and set vertex buffer(s).
// First paramter is how many buffers we have to create
glGenBuffers(1, &vbo);
// bind VBO to binding point, here it is GL_ARRAY_BUFFER
// there are other binding points
glBindBuffer(GL_ARRAY_BUFFER, vbo);//bind to context
glBufferData(GL_ARRAY_BUFFER,
sizeof(vertices),// GPU need to know how much memory needs to be allocated
vertices,//copy data to GPU
GL_STATIC_DRAW);// How to use the buffer - buffer is created and modified once
//** EBO **
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof(indices),
indices,
GL_STATIC_DRAW);
// ** Attributes **
//** Vertex 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);
// It's always a good thing to unbind any buffer/array to prevent strange bugs
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
//** Load and bind texture 1
//--------------------------
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
//** loadImage and create texture
// Load image, create texture and generate mipmaps
int width, height;
unsigned char* image = SOIL_load_image("wall.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);
// ** Load and Bind Texture 2
//---------------------------
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
//** loadImage and create texture
// Load image, create texture and generate mipmaps
unsigned char* image2 = SOIL_load_image("awesomeface.png", &width, &height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image2);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(image2);
glBindTexture(GL_TEXTURE_2D, 0);
// Set texture wrapping to GL_REPEAT (usually basic wrapping method)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
void render(){
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw our first triangle
glUseProgram(program);
//bind
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(glGetUniformLocation(program, "Texture"), 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
glUniform1i(glGetUniformLocation(program, "Texture2"), 1);
glBindVertexArray(vao);
// Draw Elements intead of vertex array
glDrawArrays(GL_QUADS, 0, 24);
//glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glutSwapBuffers();
}
void update(){
GLfloat cameraSpeed = 0.05f;
camera->setCameraSpeed(cameraSpeed);
//currentTime uniform
GLfloat currentTime = glutGet(GLUT_ELAPSED_TIME);
currentTime = currentTime / 1000;
GLint currentTimeLocation = glGetUniformLocation(program, "currentTime");
glUniform1f(currentTimeLocation, currentTime);
//transforms
glm::mat4 transform = glm::mat4(1.0f);
glm::vec3 vScaleVec = glm::vec3(0.51f, 0.51f, 0.0f);
glm::mat4 model = glm::mat4(1.0);
if (keyState[(unsigned char)'w'] == BUTTON_DOWN) {
camera->moveForward();
std::cout << "e";
}
if (keyState[(unsigned char)'s'] == BUTTON_DOWN) {
camera->moveBack();
std::cout << "A";
}
camera->Update();
//glm::mat4 projection = glm::perspective(45.0f, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f);
glm::mat4 projection = camera->getProjectionMatrix();
glm::mat4 view = glm::lookAt(camera->getCameraPos(), camera->getCameraPos() + camera->getCameraFront(), camera->getCameraUp());
//glm::mat4 view = glm::lookAt(glm::vec3(1, 1, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1));
GLfloat radius = 3.5f;
GLfloat camX = sin(currentTime) * radius;
GLfloat camZ = cos(currentTime) * radius;
//glm::mat4 view = glm::lookAt(
// glm::vec3(camX, 0.0, camZ),
// glm::vec3(0.0, 0.0, 0.0),
// glm::vec3(0.0, 1.0, 0.0));
transform = glm::scale(transform, vScaleVec);
glm::vec3(0.65f, 0.65f, 0.65f);
//transform = glm::rotate(transform, 90.0f, glm::vec3(0.0, 0.0, 1.0));
if (vCurrentPos == vPosDest && Dest1or2 == true )
{
Dest1or2 = false;
}
else if (vCurrentPos == vPosTrans && Dest1or2 == false)
{
Dest1or2 = true;
}
if(Dest1or2)
vCurrentPos = glm::mix(vCurrentPos, vPosDest, currentTime * 0.01f);
else
vCurrentPos = glm::mix(vCurrentPos, vPosTrans, currentTime*0.01f);
//transform = glm::translate(transform, vCurrentPos);
//transform = glm::translate(transform, glm::vec3(-0.51f, -0.51f, 0.0f));
//transform = glm::rotate(transform, ((GLfloat)currentTime / 100) * 90.0f, glm::vec3(0.0f, 0.0f, 1.0f));
// RTS
GLuint transformLoc = glGetUniformLocation(program, "transform");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));
GLint modelLoc = glGetUniformLocation(program, "model");
GLint viewLoc = glGetUniformLocation(program, "view");
GLint projLoc = glGetUniformLocation(program, "projection");
// Pass them to the shaders
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(camera->getViewMatrix()));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(camera->getProjectionMatrix()));
//glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
//glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
glutPostRedisplay();
}
void keyboard(unsigned char key, int x, int y) {
keyState[key] = BUTTON_DOWN;
//printf("key pressed: %d \n", key);
}
void keyboard_up(unsigned char key, int x, int y) {
keyState[key] = BUTTON_UP;
}
int main(int argc, char **argv){
// init glut
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(300, 200);
glutInitWindowSize(800, 600);
glutCreateWindow("QUAD EBO");
//init GLEW
glewInit();
init();
//clear
glClearColor(1.0, 0.0, 0.0, 1.0);//clear red
// register callbacks
glutDisplayFunc(render);
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboard_up);
glutIdleFunc(update);
glutMainLoop();
return 0;
}
Fragment Shader:
#version 430 core
in vec3 outColor;
in vec2 TexCoord;
out vec4 color;
uniform sampler2D Texture;
uniform sampler2D Texture2;
uniform float currentTime;
void main()
{
//vec3 colorTemp = outColor * abs(sin(currentTime));
//color = vec4(colorTemp, 1.0f) ;
//color = texture(ourTexture, TexCoord) * vec4(outColor, 1.0f) * abs(sin(currentTime)) ;
color = mix(texture(Texture, TexCoord), texture(Texture2, TexCoord), 0.2) * vec4(outColor, 1.0f) * abs(sin(currentTime));
}
Vertex shader:
#version 430 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
layout (location = 2) in vec2 texCoord;
out vec3 outColor;
out vec2 TexCoord;
uniform mat4 transform;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main(void)
{
gl_Position = projection * view * model * transform * vec4(position, 1.0);
outColor = color;
TexCoord = vec2(texCoord.x, 1.0 - texCoord.y);
}

If I comment out that function, it renders all the vertices as if the z-values were all 0
Well, that's because ... they are:
glm::vec3 vScaleVec = glm::vec3(0.51f, 0.51f, 0.0f);
[...]
transform = glm::scale(transform, vScaleVec);
[...]
gl_Position = projection * view * model * transform * vec4(position, 1.0);
You scale with z=0, which means you move all vertices into the z = 0 plane. So it is already flat after your first transformation step (which also means transform is a singular matrix with the third row and column being all zeros). The additional transform steps you have commented out in the code, as well as all the other matrices applied in the shader, won't change any of that, the object is still a flat plane, no matter what other matrices you pre- or post-multiply to it, they just move that plane around.
I don't know which amount of scaling you want, but scaling by 0 is almost never a good idea, and 1 is the neutral element for scaling operations.
Also, why do you have model and transform as separate matrices in the shader? In 3d computer graphics, the model matrix typically contains all the transformations required for mapping the object from it's own local model space to the world space. Even if you need to track separate parts of the transformation internally, you typically don't need these during actual rendering on the gpu, and should multiply all of these together on the CPU, and just send the accumulated transformation as the model matrix to the shader.

Related

Wrong camera movement and wrong rendering result using the framebuffer - LearnOpenGL [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 months ago.
Improve this question
I wonder if you can help me...
I followed learnopengl.com and learned the details about framebuffer. However when I am creating my own scene I found that when I press key "W", the camera moves towards the right and front. What's more, the containers, planes and the camera directions all seemed to have problems when rendering.
The results are listed below:
The direction of the camera originally wrong and when pressing W it seems like it is moving towards the right and front direction.
The rendering result also seems to have problems.
After my tests I think the problem might be the mistakenly use of glViewport. When I set the glViewport(0,0,800,600) after binding the new framebuffer, I got the output like this:
You can see the distortion disappeared however I only got things rendered on the left bottom corner...
Below is the correct output:(https://learnopengl.com/Advanced-OpenGL/Framebuffers)
This is my source code:
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include <iostream>
#include "LearnOpenGL/camera.h"
#include "LearnOpenGL/stb_image.h"
#include "glad/glad.h"
#include <GLFW/glfw3.h>
#include <LearnOpenGL/filesystem.h>
#include <LearnOpenGL/model.h>
#include "imgui-1.89/imgui.h"
void framebuffer_size_callback(GLFWwindow *window, int width, int height);
void processInput(GLFWwindow *window);
void mouse_callback(GLFWwindow *window, double xpos, double ypos);
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset);
unsigned int loadTexture(char const * path);
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
// camera attributes
Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
float lastX = SCR_WIDTH / 2.0f;
float lastY = SCR_HEIGHT / 2.0f;
bool firstMouse = true;
float fov = 45.0f;
// timing
float deltaTime = 0.0f; // time between current frame and last frame
float lastFrame = 0.0f; // time of last frame
int main() {
// glfw: initialize and configure
// ------------------------------
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
// glfw window creation
// --------------------
GLFWwindow *window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "My Playground", NULL, NULL);
if (window == NULL) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetScrollCallback(window, scroll_callback);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
// glad: load all OpenGL function pointers
// ---------------------------------------
if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
glEnable(GL_DEPTH_TEST);
Shader shader("../chapters/advanced_opengl/shaders_framebuffer/framebuffer.vert", "../chapters/advanced_opengl/shaders_framebuffer/framebuffer.frag");
Shader screenShader("../chapters/advanced_opengl/shaders_framebuffer/framebuffer_screen.vert","../chapters/advanced_opengl/shaders_framebuffer/framebuffer_screen.frag");
float cubeVertices[] = {
// positions // texture Coords
-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
};
float planeVertices[] = {
// positions // texture Coords
5.0f, -0.5f, 5.0f, 2.0f, 0.0f,
-5.0f, -0.5f, 5.0f, 0.0f, 0.0f,
-5.0f, -0.5f, -5.0f, 0.0f, 2.0f,
5.0f, -0.5f, 5.0f, 2.0f, 0.0f,
-5.0f, -0.5f, -5.0f, 0.0f, 2.0f,
5.0f, -0.5f, -5.0f, 2.0f, 2.0f
};
float quadVertices[] = { // vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates.
// positions // texCoords
-1.0f, 1.0f, 0.0f, 1.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,
1.0f, -1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f
};
// cube VAO
unsigned int cubeVAO, cubeVBO;
glGenVertexArrays(1, &cubeVAO);
glGenBuffers(1, &cubeVBO);
glBindVertexArray(cubeVAO);
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), &cubeVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
// plane VAO
unsigned int planeVAO, planeVBO;
glGenVertexArrays(1, &planeVAO);
glGenBuffers(1, &planeVBO);
glBindVertexArray(planeVAO);
glBindBuffer(GL_ARRAY_BUFFER, planeVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(planeVertices), &planeVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
// screen quad VAO
unsigned int quadVAO, quadVBO;
glGenVertexArrays(1, &quadVAO);
glGenBuffers(1, &quadVBO);
glBindVertexArray(quadVAO);
glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
unsigned int cubeTexture = loadTexture(FileSystem::getPath("resources/container.jpg").c_str());
unsigned int floorTexture = loadTexture(FileSystem::getPath("resources/metal.png").c_str());
// configuration
shader.use();
shader.setInt("texture1",0);
screenShader.use();
screenShader.setInt("screenTexture",0);
unsigned int framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
// create a color attachment texture
unsigned int textureColorbuffer;
glGenTextures(1, &textureColorbuffer);
glBindTexture(GL_TEXTURE_2D, textureColorbuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureColorbuffer, 0);
// create a renderbuffer object for depth and stencil attachment (we won't be sampling these)
unsigned int rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, SCR_WIDTH, SCR_HEIGHT);
glBindRenderbuffer(GL_RENDERBUFFER, 0); // once we've allocated enough memory for the renderbuffer object we can unbind the renderbuffer.
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); // attach the renderbuffer object to the depth and stencil attachment of the framebuffer
if(glCheckFramebufferStatus(GL_FRAMEBUFFER)!=GL_FRAMEBUFFER_COMPLETE)
{
std::cout<<"ERROR::FRAMEBUFFER:: Framebuffer is not complete!"<<std::endl;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0); // be sure to unbind the framebuffer to make sure we're not accidentally rendering to the wrong framebuffer.
// draw as wireframe
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// render loop
// -----------
while (!glfwWindowShouldClose(window)) {
// per-frame time logic
// --------------------
float currentFrame = static_cast<float>(glfwGetTime());
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
// input
// -----
processInput(window);
// render
// ------
// bind to framebuffer and draw scene as we normally would to color texture
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glEnable(GL_DEPTH_TEST); // enable depth testing (is disabled for rendering screen-space quad)
// firstly clear the screen
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shader.use();
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view = camera.GetViewMatrix();
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float) SCR_WIDTH / (float) SCR_HEIGHT, 0.1f,100.0f);
shader.setMat4("projection", projection);
shader.setMat4("view", view);
// cubes
glBindVertexArray(cubeVAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, cubeTexture);
model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(-1.0f, 0.0f, -1.0f));
shader.setMat4("model",model);
glDrawArrays(GL_TRIANGLES, 0, 36);
model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(2.0f, 0.0f, 0.0f));
shader.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, 0, 36);
// floor
glBindVertexArray(planeVAO);
glBindTexture(GL_TEXTURE_2D, floorTexture);
shader.setMat4("model", glm::mat4(1.0f));
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
// now bind back to default framebuffer and draw a quad plane with the attached framebuffer color texture
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDisable(GL_DEPTH_TEST); // disable depth test so screen-space quad isn't discarded due to depth test.
// clear all relevant buffers
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // set clear color to white (not really necessary actually, since we won't be able to see behind the quad anyways)
glClear(GL_COLOR_BUFFER_BIT);
screenShader.use();
glBindVertexArray(quadVAO);
glBindTexture(GL_TEXTURE_2D, textureColorbuffer); // use the color attachment texture as the texture of the quad plane
glDrawArrays(GL_TRIANGLES, 0, 6);
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
// -------------------------------------------------------------------------------
glfwSwapBuffers(window);
glfwPollEvents();
}
// glfw: terminate, clearing all previously allocated GLFW resources.
// ------------------------------------------------------------------
glfwTerminate();
return 0;
}
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow *window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
camera.ProcessKeyboard(FORWARD, deltaTime);
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime);
}
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow *window, int width, int height) {
// make sure the viewport matches the new window dimensions; note that width and
// height will be significantly larger than specified on retina displays.
glViewport(0, 0, width, height);
}
void mouse_callback(GLFWwindow *window, double xpos, double ypos) {
if (firstMouse) {
lastX = xpos;
lastY = ypos;
firstMouse = false;
}
float xoffset = xpos - lastX;
float yoffset = lastY - ypos; // reversed: y ranges from bottom to top
lastX = xpos;
lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset);
}
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset) {
camera.ProcessMouseScroll(static_cast<float>(yoffset));
}
unsigned int loadTexture(char const * path)
{
unsigned int textureID;
glGenTextures(1, &textureID);
int width, height, nrComponents;
unsigned char *data = stbi_load(path, &width, &height, &nrComponents, 0);
if (data)
{
GLenum format;
if (nrComponents == 1)
format = GL_RED;
else if (nrComponents == 3)
format = GL_RGB;
else if (nrComponents == 4)
format = GL_RGBA;
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
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_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
stbi_image_free(data);
}
else
{
std::cout << "Texture failed to load at path: " << path << std::endl;
stbi_image_free(data);
}
return textureID;
}
This is my framebuffer.vert:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoords;
out vec2 TexCoords;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
TexCoords = aTexCoords;
gl_Position = projection * view * model * vec4(aPos, 1.0);
}
This is my framebuffer.frag:
#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D texture1;
void main()
{
FragColor = texture(texture1, TexCoords);
}
This is my framebuffer_screen.vert:
#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aTexCoords;
out vec2 TexCoords;
void main()
{
TexCoords = aTexCoords;
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
}
This is my framebuffer_screen.frag:
#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D screenTexture;
void main()
{
FragColor = texture(screenTexture, TexCoords);
}
I tried to find the problem but I couldn't figure it out... I would appreciate it if you could help me. Thank you so much.
This is caused by the difference between width / height in raw pixels (i.e. number of physical pixels) v.s. width / height in screen coordinates (i.e. logical window size). There is a note on the GLFW window guide that says:
Do not pass the window size to glViewport or other pixel-based OpenGL calls. The window size is in screen coordinates, not pixels. Use the framebuffer size, which is in pixels, for pixel-based calls.
glfwCreateWindow() requires the width and height to be in screen coordinates. Therefore, the SCR_WIDTH and SCR_HEIGHT are in screen coordinates. All other places, however, require width and height in raw pixels, which can be obtained by either
saving the width and height values passed to your framebuffer_size_callback callback function, or
calling glfwGetFramebufferSize from your main function, which is easier.
Using the framebuffer size (instead of SCR_WIDTH and SCR_HEIGHT) to calculate all the rendering stuff for the gl* calls solves your issue.

Legacy OpenGL: What's wrong with my shadow mapping code? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 months ago.
Improve this question
I'm trying to implement shadow mapping in legacy OpenGL (yes, I know it's deprecated but however), but it's not working right. Almost everything is black (see picture, in the lower left I added a view from the light source). I checked the depth texture and projection and everything seems correct for me.
I have a diffuse texture in Texture Unit 0 and the depth texture is in Texture Unit 1.
My initialization code:
void InitScene()
{
light1_projection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, 1.0f, 100.0f);
light1_view = glm::lookAt(glm::vec3(30.0f, 35.0f, 30.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
camera_projection = glm::perspective(glm::radians(45.0f), 1.333f, 1.0f, 300.0f);
camera_view = glm::lookAt(glm::vec3(0.0f, 30.0f, 20.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
bias = glm::mat4(
0.5f, 0.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 5.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f
);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glClearColor(0.2f, 0.2f, 1.0f, 1.0f);
LoadTexture(); // Loads the diffuse texture in TMU 0
InitShadowmapTexture();
}
void InitShadowmapTexture()
{
glActiveTexture(GL_TEXTURE1);
glGenTextures(1, &shadowmap_texture);
glBindTexture(GL_TEXTURE_2D, shadowmap_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
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_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
shadowmap_width, shadowmap_heigth, 0,
GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glEnable(GL_TEXTURE_GEN_Q);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
}
My render code:
void Render()
{
RenderShadowMap();
RenderNormalScene();
RenderNormalSceneLightView();
}
void DrawScene(const glm::mat4 &view, const glm::mat4 &projection)
{
const auto plane = glm::translate(view, glm::vec3(0.0f, 0.0f, 0.0f));
const auto cube1 = glm::translate(view, glm::vec3(0.0f, 3.0f, z)) *
glm::rotate(glm::mat4(1.0f), glm::radians(rotx), glm::vec3(1.0f, 0.0f, 0.0f)) *
glm::rotate(glm::mat4(1.0f), glm::radians(roty), glm::vec3(0.0f, 1.0f, 0.0f));
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(glm::value_ptr(projection));
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(glm::value_ptr(view));
glActiveTexture(GL_TEXTURE1);
const auto planes = bias * light1_projection * light1_view;
glTexGenfv(GL_S, GL_EYE_PLANE, glm::value_ptr(glm::row(planes, 0)));
glTexGenfv(GL_T, GL_EYE_PLANE, glm::value_ptr(glm::row(planes, 1)));
glTexGenfv(GL_R, GL_EYE_PLANE, glm::value_ptr(glm::row(planes, 2)));
glTexGenfv(GL_Q, GL_EYE_PLANE, glm::value_ptr(glm::row(planes, 3)));
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(glm::value_ptr(plane));
DrawPlane(20.0f, 20.0f);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(glm::value_ptr(cube1));
DrawCube(size, size, size);
}
void RenderNormalScene()
{
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glCullFace(GL_BACK);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glViewport(0, 0, screen_width, screen_heigth);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
DrawScene(camera_view, camera_projection);
}
void RenderNormalSceneLightView()
{
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glEnable(GL_SCISSOR_TEST);
glScissor(0, 0, screen_width / 6, screen_heigth / 6);
glCullFace(GL_BACK);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glViewport(0, 0, screen_width / 6, screen_heigth / 6);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
DrawScene(light1_view, light1_projection);
glDisable(GL_SCISSOR_TEST);
}
void RenderShadowMap()
{
glActiveTexture(GL_TEXTURE1);
glDisable(GL_TEXTURE_2D);
glCullFace(GL_FRONT);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glViewport(0, 0, shadowmap_width, shadowmap_heigth);
glClear(GL_DEPTH_BUFFER_BIT);
DrawScene(light1_view, light1_projection);
glActiveTexture(GL_TEXTURE1);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, shadowmap_width, shadowmap_heigth);
}
Do you have any ideas how to solve this issue?
You have set the bias value to
bias = glm::mat4(
0.5f, 0.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 5.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f
);
In row 2, column 2, you have set the value to 5.0f, instead of 0.5f. This has the effect of scaling the z value by 5 instead of by 0.5; thus your error.
The correct bias matrix is
bias = glm::mat4(
0.5f, 0.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f
);

OpenGL C++, Cubemap, vertexshader [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I'm currently learning OpengGL and i can't seem to resolve this "void" error in my vertexshader. No issue with my fragmentshader or main.cpp file thus far. any input is greatly appreciated...............................................................................
Include standard headers
#include <stdio.h>
#include <stdlib.h>
#include GLEW
#include <GL/glew.h>
#include <vector>
#include <iostream>
// Include GLFW
#include <GLFW/glfw3.h>
GLFWwindow* window;
// Include GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;
#include <common/skyboxtex.hpp>
#include <common/shader.hpp>
#include <common/texture.hpp>
#include <common/controls.hpp>
#include <glm/gtc/type_ptr.hpp>
int main( void )
{
// Initialise GLFW
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
getchar();
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 0 - Keyboard and Mouse", 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);
// 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);
// Accept fragment if it closer to the camera than the former one
glDepthFunc(GL_LESS);
// Cull triangles which normal is not towards the camera
glEnable(GL_CULL_FACE);
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// Create and compile our GLSL program from the shaders
GLuint programID = LoadShaders( "TransformVertexShader.vertexshader", "TextureFragmentShader.fragmentshader");
GLuint skyboxShader = LoadShaders("skybox.FragmentShader", "skybox.VertexShader");
// Get a handle for our "MVP" uniform
GLuint MatrixID = glGetUniformLocation(programID, "MVP");
GLuint ModelMatrixID = glGetUniformLocation(programID, "M");
GLuint ViewMatrixID = glGetUniformLocation(programID, "V");
// Load the texture
GLuint Texture = loadDDS("uvtemplate.DDS");
// Get a handle for our "myTextureSampler" uniform
GLuint TextureID = glGetUniformLocation(programID, "myTextureSampler");
//static GLuint terrainVbo = 0, terraininVboNorm = 0, terrainEbo = 0;
//static int terrainCount = 0;
//skyboxvertieces
float skyboxVertices[] = {
// positions
-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,
-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,
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,
-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,
-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,
-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
};
// Our vertices. Tree consecutive floats give a 3D vertex; Three consecutive vertices give a triangle.
// A cube has 6 faces with 2 triangles each, so this makes 6*2=12 triangles, and 12*3 vertices
static const GLfloat g_vertex_buffer_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,
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,
-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,
-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,
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,
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
};
// Two UV coordinatesfor each vertex. They were created with Blender.
static const GLfloat g_uv_buffer_data[] = {
0.000059f, 0.000004f,
0.000103f, 0.336048f,
0.335973f, 0.335903f,
1.000023f, 0.000013f,
0.667979f, 0.335851f,
0.999958f, 0.336064f,
0.667979f, 0.335851f,
0.336024f, 0.671877f,
0.667969f, 0.671889f,
1.000023f, 0.000013f,
0.668104f, 0.000013f,
0.667979f, 0.335851f,
0.000059f, 0.000004f,
0.335973f, 0.335903f,
0.336098f, 0.000071f,
0.667979f, 0.335851f,
0.335973f, 0.335903f,
0.336024f, 0.671877f,
1.000004f, 0.671847f,
0.999958f, 0.336064f,
0.667979f, 0.335851f,
0.668104f, 0.000013f,
0.335973f, 0.335903f,
0.667979f, 0.335851f,
0.335973f, 0.335903f,
0.668104f, 0.000013f,
0.336098f, 0.000071f,
0.000103f, 0.336048f,
0.000004f, 0.671870f,
0.336024f, 0.671877f,
0.000103f, 0.336048f,
0.336024f, 0.671877f,
0.335973f, 0.335903f,
0.667969f, 0.671889f,
1.000004f, 0.671847f,
0.667979f, 0.335851f
};
//Skybox
GLuint skyboxVAO, skyboxVBO;
glGenVertexArrays(1, &skyboxVAO);
glGenBuffers(1,&skyboxVBO);
glBindVertexArray(skyboxVAO);
glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT,GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glBindVertexArray(0);
//skybox image faces
std::vector <std::string>faces;
{
"right.BMP",
"left.BMP",
"top.BMP",
"bottom.BMP",
"front.BMP",
"back.BMP";
};
unsigned int CubemapTexture = loadCubemap(faces);
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
GLuint uvbuffer;
glGenBuffers(1, &uvbuffer);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_uv_buffer_data), g_uv_buffer_data, GL_STATIC_DRAW);
do{
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Use our shader
glUseProgram(programID);
glUseProgram(skyboxShader);
// Compute the MVP matrix from keyboard and mouse input
computeMatricesFromInputs();
glm::mat4 ProjectionMatrix = getProjectionMatrix();
glm::mat4 ViewMatrix = getViewMatrix();
glm::mat4 ModelMatrix = glm::mat4(1.0);
glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;
glm::mat4 view = glm::mat4(glm::mat3(getViewMatrix()));
// skybox Uniform INCLUDE glm value_PTR.hpp
glUniformMatrix4fv(glGetUniformLocation(skyboxShader, "view"), 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(glGetUniformLocation(skyboxShader, "projection"), 1, GL_FALSE, glm::value_ptr(ProjectionMatrix));
// Send our transformation to the currently bound shader,
// in the "MVP" uniform
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
// Bind our texture in Texture Unit 0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, Texture);
// Set our "myTextureSampler" sampler to use Texture Unit 0
glUniform1i(TextureID, 0);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// 2nd attribute buffer : UVs
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glVertexAttribPointer(
1, // attribute. No particular reason for 1, but must match the layout in the shader.
2, // size : U+V => 2
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, 12*3); // 12*3 indices starting at 0 -> 12 triangles
glm::mat4 ModelMatrix2 = glm::mat4(1.0);
ModelMatrix2 = glm::translate(ModelMatrix2, glm::vec3(2.0f, 0.0f, 0.0f));
glm::mat4 MVP2 = ProjectionMatrix * ViewMatrix * ModelMatrix2;
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP2[0][0]);
glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &ModelMatrix2[0][0]);
// 2nd object
glDrawArrays(GL_TRIANGLES, 0, 12 * 3);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
// 2nd attribute buffer : UVs
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
//newshit
glBindVertexArray(skyboxVAO);
glDepthFunc(GL_LEQUAL);
glUseProgram(skyboxShader);
glBindTexture(GL_TEXTURE_CUBE_MAP, CubemapTexture);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glDepthFunc(GL_LESS);
// 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 );
// Cleanup VBO and shader
glDeleteBuffers(1, &vertexbuffer);
glDeleteBuffers(1, &uvbuffer);
glDeleteProgram(programID);
glDeleteTextures(1, &TextureID);
glDeleteVertexArrays(1, &VertexArrayID);
// Close OpenGL window and terminate GLFW
glfwTerminate();
return 0;
}
This is the skybox vertexshader
#version 330 core
layout (location = 0) in vec3 position;
out vec3 TexCoords;
uniform mat4 projection;
uniform mat4 view;
out gl_PerVertex
{
vec4 gl_position;
}
ERROR: 0:22: 'void' : syntax error syntax error
void main() <--?? error
{
vec4 pos = projection * view * vec4(position, 1.0);
gl_Position = pos.xyww;
TexCoords = position;
}
skybox fragmentshader
#version 330 core
in vec3 TexCoords;
out vec4 color;
uniform samplerCube skybox;
void main()
{
color = texture(skybox, TexCoords);
}
You can avoid using block syntax to simplify your shader. I noticed a number of potential issues/syntax errors with your vertex shader (eg the redundant use of the gl_PerVertex block, missing semicolons, etc).
Also wasn't sure if you intended to pass pos.xyww or pos.xyzw to gl_Position as this looked non-standard to me.
Try this:
#version 330 core
layout (location = 0) in vec3 position;
out vec3 TexCoords;
uniform mat4 projection;
uniform mat4 view;
void main()
{
vec4 pos = projection * view * vec4(position.xyz, 1.0);
gl_Position = pos;
TexCoords = position;
}

C++ Texture not displaying correctly: Merging into 1 colour

I'm attempting to texture a VBO/VAO model cube. The cube is definitely rendering/drawn correctly, and as far as I know I am doing everything needed to load the texture.
However when it comes to applying the texture it appears to take an average of all colours in the texture, then apply that average to the entire cube. This results in it appearing to be "painted" with a plain, regular colour as shown in the screenshot below:
this is the texture;
I'm at a loss as to why this is happening. Below is the code from my init, loadTexture and display functions (I did not write the loadTexture function):
Init Function
(Only showing the code relevant to the cube + texture)
void init(void) {
.
.
.
pyramidTexture = TextureLoader::fiLoadTexture(wstring(L"Common\Resources\Textures\Sandstone.png"));
// Setup VAO for pyramid object
glGenVertexArrays(1, &pyramidVAO);
glBindVertexArray(pyramidVAO);
// Setup VBO for vertex position data
glGenBuffers(1, &pyramidVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, pyramidVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(pyramidVertices), pyramidVertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)0); // attribute 0 gets data from bound VBO (so assign vertex position buffer to attribute 0)
// Setup VBO for vertex colour data
glGenBuffers(1, &pyramidColourBuffer);
glBindBuffer(GL_ARRAY_BUFFER, pyramidColourBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(pyramidColours), pyramidColours, GL_STATIC_DRAW);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_TRUE, 0, (const GLvoid*)0); // attribute 1 gets colour data
glGenBuffers(3, &pyramidTexCoordBuffer);
glBindBuffer(GL_ARRAY_BUFFER, pyramidTexCoordBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(pyramidTexCoordArray), pyramidTexCoordArray, GL_STATIC_DRAW);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)0);
// Enable vertex position and colour + Texture attribute arrays
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(3);
// Setup VBO for face index array
glGenBuffers(1, &pyramidIndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pyramidIndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(pyramidVertexIndices), pyramidVertexIndices, GL_STATIC_DRAW);
glBindVertexArray(0);
glEnable(GL_NORMALIZE); // If we scale objects, ensure normal vectors are re-normalised to length 1.0 to keep lighting calculations correct (see lecture notes)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Best colour interpolation results
.
.
.
}
LoadTexture Function
GLuint TextureLoader::fiLoadTexture(const wstring& textureFilePath) {
BOOL fiOkay = FALSE;
GLuint newTexture = 0;
fipImage I;
// Convert wstring to const char*
wstring_convert<codecvt_utf8<wchar_t>, wchar_t> stringConverter;
string S = stringConverter.to_bytes(textureFilePath);
const char *filename = S.c_str();
// Call FreeImage to load the image file
fiOkay = I.load(filename);
if (!fiOkay) {
cout << "FreeImagePlus: Cannot open image file.\n";
return 0;
}
fiOkay = I.flipVertical();
fiOkay = I.convertTo24Bits();
if (!fiOkay) {
cout << "FreeImagePlus: Conversion to 24 bits successful.\n";
return 0;
}
auto w = I.getWidth();
auto h = I.getHeight();
BYTE *buffer = I.accessPixels();
if (!buffer) {
cout << "FreeImagePlus: Cannot access bitmap data.\n";
return 0;
}
glGenTextures(1, &newTexture);
glBindTexture(GL_TEXTURE_2D, newTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGR, GL_UNSIGNED_BYTE, buffer);
// Setup default texture properties
if (newTexture) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
return newTexture;
}
Display Function
void display(void) {
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Set viewport to the client area of the current window
glViewport(0, 0, glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
// Get view-projection transform as a GUMatrix4
GUMatrix4 T = mainCamera->projectionTransform() * mainCamera->viewTransform();
if (principleAxes)
principleAxes->render(T);
if (texturedQuad)
texturedQuad->render(T * GUMatrix4::translationMatrix(0.5f, 0.5f, 0.0f));
// Fixed function rendering (Compatability profile only) - use this since CGImport is written against OpenGL 2.1
glUseProgram(0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMultMatrixf((const float*)mainCamera->projectionTransform().M);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMultMatrixf((const float*)mainCamera->viewTransform().M);
glMultMatrixf((const float*)GUMatrix4::translationMatrix(0.0f, -0.15f, 0.0f).M);
glEnable(GL_TEXTURE_2D);
glPolygonMode(GL_FRONT, GL_FILL);
if (exampleModel)
exampleModel->renderTexturedModel();
glDisable(GL_TEXTURE_2D);
//Define position and direction (so appear at fixed point in scene)
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightDirection);
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
// enable texturing
glEnable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
//
// Pyramid VBO rendering
//
// Use basic shader for rendering pyramid (we'll look at this in more detail next week)
glUseProgram(basicShader);
static GLint mvpLocationPyramid = glGetUniformLocation(basicShader, "mvpMatrix");
glUniformMatrix4fv(mvpLocationPyramid, 1, GL_FALSE, (const GLfloat*)&(T.M));
GUMatrix4 pyramidModelTransform = GUMatrix4::translationMatrix(-5.75f, 0.0f, 0.0f) * GUMatrix4::scaleMatrix(2.0f, 2.0f, 2.0f);
GUMatrix4 mvpPyramid = T * pyramidModelTransform;
glUniformMatrix4fv(mvpLocationPyramid, 1, GL_FALSE, (const GLfloat*)&(mvpPyramid.M));
// Bind VAO that contains all relevant pyramid VBO buffer and attribute pointer bindings
glBindVertexArray(pyramidVAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, pyramidTexture);
// Draw pyramid
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, (const GLvoid*)0);
// Unbind pyramid VAO (or bind another VAO)
glBindVertexArray(0);
glutSwapBuffers();
}
I've been trying to fix this for hours now without any luck, as such any support would be massively appreciated!!!
EDIT: Added in VAO attributes + Shaders
VAO Settings
// Per-vertex position vectors
static float pyramidVertices[32] =
{
//Front
0.0f, 0.0f, 0.0f, 1.0f, //BtmLeft
1.0f, 0.0f, 0.0f, 1.0f, //BtmRight
1.0f, 1.0f, 0.0f, 1.0f, //TopRight
0.0f, 1.0f, 0.0f, 1.0f, //TopLeft
//Back
0.0f, 1.0f, 1.0f, 1.0f, //TopLeft
1.0f, 1.0f, 1.0f, 1.0f, //TopRight
1.0f, 0.0f, 1.0f, 1.0f, //BottomRight
0.0f, 0.0f, 1.0f, 1.0f //BottomLeft
};
// Per-vertex colours (RGBA) floating point values
static float pyramidColours[32] =
{
1.0f, 0.0f, 0.0f, 1.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,
0.0f, 1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f
};
// 5 faces each with 3 vertices (each face forms a triangle)
static unsigned short pyramidVertexIndices[36] =
{
//Front
0, 3, 2,
2, 1, 0,
//Right
4, 3, 0,
0, 7, 4,
//Back
4, 7, 6,
6, 5, 4,
//Top
4, 5, 3,
3, 5, 2,
//Left
2, 5, 1,
1, 5, 6,
//Bottom
6, 7, 0,
0, 1, 6
};
static unsigned short pyramidTexCoordArray[24] =
{
-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,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f
};
Vertex Shader
#version 330
uniform mat4 mvpMatrix;
layout (location=0) in vec4 vertexPos;
layout (location=3) in vec2 vertexTexCoord;
out vec2 texCoord;
void main(void) {
mat4 M;
M[0] = vec4(1.0);
ivec2 a = ivec2(1, 2);
//vec3 b = vec3(2.0, 4.0, 1.0) + a;
texCoord = vertexTexCoord;
gl_Position = mvpMatrix * vertexPos;
}
Fragment Shader
#version 330
uniform sampler2D texture;
in vec2 texCoord;
layout (location=0) out vec4 fragColour;
void main(void) {
vec4 texColor = texture2D(texture, texCoord);
fragColour = texColor;
}
You defined your data as unsigned short:
static unsigned short pyramidTexCoordArray[24]
But it has to be float.
There are a lot of things strange:
You are generating 3 VBOs for texture coordinates, but are just using one. Unless pyramidTexCoordBuffer is of type GLuint[3] (which I assume it is not due to the &), you are writing out of bounds.
Edit: This refers to the glGenBuffers(3, &pyramidTexCoordBuffer); line, which allocates 3 buffers and stores them in three consecutive GLuint variables starting at pyramidTexCoordBuffer. Since pyramidTexCoordBuffer is most probably a GLuint, pyramidTexCoordBuffer[1] and pyramidTexCoordBuffer[2] refer to unallocated memory.
The pyramidTexCoordArray array is specified as unsigned short, but you are writing floats to it. Since it is unsigned, at least the negative numbers will be gone.
Additionally, you tell OpenGL with the
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)0);
line that the data is of type GL_FLOAT (which it is not) and that it has two floats per vertex (but the data has 3 elements per vertex):

SDL_TTF draws garbage

I asked a question the other day, about rendering TTF fonts using SDL, and was pointed towards SDL_TTFL I've tried using the SDL_TTF library, but All I'm getting is garbage on screen
I have included my shaders, which are very simple for this program, and also the snipped I'm using to load the text into surface, and to bind it to the texture. I'm not trying to do anything crazy here at all. Is there anything I'm doing wrong you can see? I'm not really too sure how to debug shaders etc.
Fragment Shader (frag.glsl):
#version 330
in vec2 texCoord;
in vec4 fragColor;
out vec3 finalColor;
uniform sampler2D myTextureSampler;
void main() {
finalColor = texture( myTextureSampler, texCoord ).rgb;
}
Vertex Shader (vert.glsl)
#version 330
in vec3 vert;
in vec4 color;
in vec2 texcoord;
out vec4 fragColor;
out vec2 texCoord;
void main() {
fragColor = color;
gl_Position = vec4(vert, 1);
texCoord = texcoord;
}
Font Loading (loadFont.cpp)
//Initialise TTF
if( TTF_Init() == -1 )
throw std::runtime_error("SDL_TTF failed to initialise.");
//Load the texture
font = TTF_OpenFont( filePath.c_str(), 12 );
if(!font)
throw std::runtime_error("Couldn't load: "+ filePath);
TTF_SetFontStyle(font, TTF_STYLE_NORMAL);
surface = TTF_RenderUTF8_Blended(font, "Hello", this->textColor);
Uint8 colors = surface->format->BytesPerPixel;
int texture_format;
if (colors == 4) { // alpha
if (surface->format->Rmask == 0x000000ff)
texture_format = GL_RGBA;
else
texture_format = GL_BGRA;
} else { // no alpha
if (surface->format->Rmask == 0x000000ff)
texture_format = GL_RGB;
else
texture_format = GL_BGR;
}
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, colors, surface->w, surface->h, 0,
texture_format, GL_UNSIGNED_BYTE, surface->pixels);
SDL_FreeSurface(surface);
Vertex Attribute Setup
GLfloat vertices[] = {
//X Y Z R G B A U V
-1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, 0.f, 1.f,
1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, 1.f, 1.f,
-1.0f, -0.4f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, 0.f, 0.f,
1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, 1.f, 1.f,
1.0f, -0.4f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, 1.f, 0.f,
-1.0f, -0.4f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, 0.f, 0.f
};
glGenVertexArrays(1, &_vao);
glBindVertexArray(_vao);
glGenBuffers(1, &_vbo);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(program->attrib("vert"));
glVertexAttribPointer(program->attrib("vert"), 3, GL_FLOAT, GL_FALSE, 9*sizeof(GLfloat), NULL);
glEnableVertexAttribArray(program->attrib("color"));
glVertexAttribPointer(program->attrib("color"), 4, GL_FLOAT, GL_TRUE, 9*sizeof(GLfloat), (const GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(program->attrib("texcoord"));
glVertexAttribPointer(program->attrib("texcoord"), 2, GL_FLOAT, GL_TRUE, 9*sizeof(GLfloat), (const GLvoid*)(7 * sizeof(GLfloat)));
I've attached the code I'm using for the vertex attributes as per the comment below.
EDIT:
In a reply that has been deleted since, It was asked whether SDL_TTF was returning 3 or 4 channels. It's returning a BGRA image. I've tried changing my fragment shader to
Fragment shader
#version 330
in vec2 texCoord;
in vec4 fragColor;
out vec4 finalColor;
uniform sampler2D myTextureSampler;
void main() {
finalColor = texture( myTextureSampler, texCoord ).rgba;
}
Note the vec4, and using rgba rather than rgb. This just leads to a black rectangle.
I also tried generating a surface using SDL_LoadBMP(), which gives the exact same results.
Your call to
glTexImage2D(GL_TEXTURE_2D, 0, colors, surface->w, surface->h, 0,
texture_format, GL_UNSIGNED_BYTE, surface->pixels);
Is a problem.
The third paramter is wrong:
http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml
internalFormat
Specifies the number of color components in the texture.
Must be one of base internal formats given in Table 1,
one of the sized internal formats given in Table 2, or one
of the compressed internal formats given in Table 3, below.
I suspect you want yours to be GL_RGBA (or what format you want opengl to store your texture in)
EDIT:
I just saw it now, but you are using only 3 channels in your fragment shader. The Blended function requires that you use 4 channels otherwise the alpha channel is going to be messed up.
I think your "main" problem lies somewhere else though as that should just make the colour constant over the entire surface. (Not the "garbage" you are seeing)
I quickly wrote this program that mostly does what your doing. I think it will help you more than my repository as it's straight to the point.
#include <GL/glew.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>
#include <SDL2/SDL_ttf.h>
#include <string>
#include <iostream>
using namespace std;
SDL_Window *window = NULL;
SDL_GLContext context = NULL;
TTF_Font* font = NULL;
SDL_Surface* surface = NULL;
//OpenGL Objects
GLuint vao;
GLuint vbo;
GLuint texture;
//Shader Objects
GLuint program;
GLuint vs;
GLuint fs;
//Sampler Object
GLuint uniformSampler;
//Callback Function
APIENTRY GLvoid debugMessageCallbackFunction( GLenum source, GLenum type, GLuint id, GLenum severity,
GLsizei length, const GLchar* message, GLvoid* userParam)
{
cerr << endl << "\t" << message << endl;
}
//The shaders are identical to yours
const string fragmentShaderString =
"#version 130\n" // My laptop can't do OpenGL 3.3 so 3.0 will have to do
"in vec2 texCoord;\n"
"in vec4 fragColor;\n"
"\n"
"out vec4 finalColor;\n"
"\n"
"uniform sampler2D myTextureSampler;\n"
"void main() {\n"
" finalColor = texture( myTextureSampler, texCoord ) * fragColor;\n"
"}";
const string vertexShaderString =
"#version 130\n"
"\n"
"in vec3 vert;\n"
"in vec4 color;\n"
"in vec2 texcoord;\n"
"\n"
"out vec4 fragColor;\n"
"out vec2 texCoord;\n"
"void main() {\n"
" fragColor = color;\n"
" gl_Position = vec4(vert, 1);\n"
" texCoord = texcoord;\n"
"}\n";
//Your vertices, but I changed alpha to 1.0f
const GLfloat vertices[] =
{
//X Y Z R G B A U V
-1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.f, 1.f,
1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.f, 1.f,
-1.0f, -0.4f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.f, 0.f,
1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.f, 1.f,
1.0f, -0.4f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.f, 0.f,
-1.0f, -0.4f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.f, 0.f
};
int main(int argc, char* args[])
{
//Create Window and Context
window = SDL_CreateWindow("SDL Text with OpenGL", 0, 0, 640, 480, SDL_WINDOW_OPENGL);
//Set Core Context
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 1 );
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
context = SDL_GL_CreateContext(window);
//Simple OpenGL State Settings
glViewport( 0.f, 0.f, 640.f, 480.f);
glClearColor( 0.f, 0.f, 0.f, 1.f);
//Init Glew
//Set glewExperimental for Core Context
glewExperimental=true;
glewInit();
//Set Blending
//Required so that the alpha channels show up from the surface
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//Simple callback function for GL errors
glDebugMessageCallbackARB(debugMessageCallbackFunction, NULL);
//Create Shaders
vs = glCreateShader(GL_VERTEX_SHADER);
fs = glCreateShader(GL_FRAGMENT_SHADER);
//Source Pointers
const GLchar* vsSource= &vertexShaderString[0];
const GLchar* fsSource = &fragmentShaderString[0];
//Set Source
glShaderSource(vs, 1, &vsSource, NULL);
glShaderSource(fs, 1, &fsSource, NULL);
//Compile Shaders
glCompileShader(fs);
glCompileShader(vs);
//Create Shader Program
program = glCreateProgram();
//Attach Shaders to Program
glAttachShader(program, vs);
glAttachShader(program, fs);
//No need for shaders anymore
glDeleteShader(vs);
glDeleteShader(fs);
//Set Attribute Locations
glBindAttribLocation(program, 0, "vert");
glBindAttribLocation(program, 1, "color");
glBindAttribLocation(program, 2, "texcoord");
//Link Program
glLinkProgram(program);
//Setup VAO and VBO
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 9 * 6, vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat), NULL);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat),(GLvoid*)(3*sizeof(GLfloat)));
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat),(GLvoid*)(7*sizeof(GLfloat)));
//Init TTF
TTF_Init();
//Open Font
font = TTF_OpenFont("DroidSansFallbackFull.ttf", 30);
SDL_Color color = {255, 255, 255, 255};
//Create Surface
surface = TTF_RenderUTF8_Blended(font, "This is TEXT!", color);
//Your format checker
GLenum format = (surface->format->BytesPerPixel==3)?GL_RGB:GL_RGBA;
//Create OpenGL Texture
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D( GL_TEXTURE_2D, 0, format, surface->w, surface->h, 0,
format, GL_UNSIGNED_BYTE, surface->pixels);
//Set Some basic parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//Set up Sampler
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
uniformSampler = glGetUniformLocation(program, "myTextureSampler");
//It defaults to using GL_TEXTURE0, so it's not necessary to set it
//in this program it's generally a good idea.
//--------------------------------------------------------------------------------------
// DRAW STAGE
//--------------------------------------------------------------------------------------
glUseProgram(program);
//glBindVertexArray(vao); - still in use
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 6);
SDL_GL_SwapWindow(window);
//Sleep for 2s before closing
SDL_Delay(2000);
}
I didn't do any error checking or close any of the resources since it's just meant to be a reference and not meant to be used.
Usually I don't use glew, but writing code to manually get the functions for such a small program seemed pointless.
It compiles with
g++ source.cpp -g -lSDL2 -lSDL2_ttf -lGL -GLEW -o demo
on linux. You might need to make some adjustments for Windows (Headers files might change slightly and libraries will change as wel) and I think it will work without change on Mac.
EDIT 2:
To compile it on windows with mingw you need to add APIENTRY to callback function and the main should have arguments. Changed code to reflect this.
Tested it and it works on both windows and linux. (Provided that your implementation have access to the GL_ARB_debug_callback extension, if not just comment that out)
Does work nicely, only got to edit the const GLfloat vertices[] array to be able to change the text color consistently. For a solid color text, have all RGB components in the array equal to 1.0f and render the texture in color. For a multicolored text, first render the texture in white with SDL_Color color = { 255, 255, 255, 255 };, then edit the array as shown here below.
float width = (float)surface->w;
float height = (float)surface->h;
// alpha to 1.0f
const GLfloat vertices[] = {
// X Y Z R G B A U V
-1.0, -height / width, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.0f, -height / width, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, height / width, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
1.0f, -height / width, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, height / width, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
-1.0f, height / width, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f
};