So far I've learned how to create a cube with textures in OpenGL.
Now I want to change this code for texturing a Quad. I've changed the vertices + indices from a cube to a quad.
And the Quad looks like this:
The texture is completely distorted and the upper triangle is missing...
This is the code I'm using:
1.
GLfloat vertices[] = {
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
unsigned int indices[]{
0,1,2,
1,2,3,
};
2.
for (size_t o = 0; o < 6; o++) {
glPixelStorei(GL_UNPACK_ROW_LENGTH, breite_komplett);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, ausschnitt_x_counter);
glPixelStorei(GL_UNPACK_SKIP_ROWS, ausschnitt_y_counter);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(
GL_TEXTURE_CUBE_MAP_POSITIVE_X + o, 0, GL_RGBA, ausschnitt_breite, ausschnitt_höhe, 0, GL_RGBA, GL_UNSIGNED_BYTE, sprite_image.getPixelsPtr());
}
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
glEnable(GL_TEXTURE_2D);
Do you have an ideas what I need to change?
Edit:
unsigned int indices[]{
0,1,2,
0,2,3
};
This is my object builder:
glGenVertexArrays(1, &obj_vao);
glBindVertexArray(obj_vao);
glGenBuffers(1, &obj_ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, obj_ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indicies[0])* indicies_count, indicies, GL_STATIC_DRAW);
glGenBuffers(1, &obj_vbo);
glBindBuffer(GL_ARRAY_BUFFER, obj_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * count_vertices, vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertices[0]) * 5, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vertices[0]) * 5, (void*)(sizeof(vertices[0]) * 3));
glEnableVertexAttribArray(1);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
Edit:
If the vertices would be like this:
GLfloat vertices[] = {
1.0f, 1.0f, -1.0f, 1.0f, 1.0f,
1.0f, -1.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
};
Everything would be fine and the Quad looks like this:
But I need the Quad in the origin like this:
GLfloat vertices[] = {
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
With this vertices the texture is distorted...
The indices of the 2 triangle primitives do not form a quad. The indices have to be:
unsigned int indices[]{ 0, 1, 2, 1, 2, 3 };
unsigned int indices[]{ 0, 1, 2, 0, 2, 3 };
3 0
+-----+ +
| / / |
| / / |
+ +-----+
2 1
When you crate the texture, the you mix GL_TEXTURE_CUBE_MAP and GL_TEXTURE_2D. That makes no sense. Either create a cubemap texture and set the parameters for the GL_TEXTURE_CUBE_MAP or create a 2 dimensional texture.
Anyway if you want to create a cubemap texture, then you have to use GL_TEXTURE_CUBE_MAP, when you set the parameters, too.
The texture coordinate for a texture cube is a 3 dimensional vector. Change the vertex coordinates for the side of the cube. e.g:
(You don't need the texture coordinates at all)
GLfloat vertices[] = {
// x y z
1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, -1.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
};
The center of the cube is (0, 0, 0), so you can use the vertex coordinates for the texture, too:
Vertex shader
in vec3 position;
out vec3 cubeCoord;
void main()
{
cubeCoord = position;
// [...]
}
Fragment shader:
in vec3 cubeCoord;
uniform samplerCube cubeTex;
void main()
{
vec4 color = texture(cubeTex, cubeCoord);
// [...]
}
Alternatively you can use separate 3 dimensional texture coordinates for the cubemap texture:
GLfloat vertices[] = {
// x y z u v w
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, 0.0f, -1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 1.0f,
};
Related
The image I am trying to load is turned 90 degrees when rendered. I am using "stbi flip image vertically on load" but when the texture is rendered, the image is turned 90 degrees.
I tried to change the index and tex coords, that didnt work.
//Mesh struct
Mesh mesh = {
// Position // Color // Tex coords
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 1.0f,
// Index
0,1,2,2,3,0
};
//The other code
/*Texture*/
int width, height, bpp;
unsigned char* image;
string path = "res/textures/Brick.png";
unsigned int texture;
stbi_set_flip_vertically_on_load(1);
image = stbi_load(path.c_str(), &width, &height, &bpp, 4);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
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_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, image);
if (image)
stbi_image_free(image);
glActiveTexture(GL_TEXTURE0);
glUniform1i(glGetUniformLocation(shader, "Texture"), 0);
/*Position*/
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float),
(void*)0);
glEnableVertexAttribArray(0);
/*Color*/
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 9 * sizeof(float),
(void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
/*Texture*/
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 9 * sizeof(float),
(void*)(7 * sizeof(float)));
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
The texture should apear as the image and not rotated 90 degrees.
Image: https://opengameart.org/sites/default/files/oga-textures/brick_base.png
You said I tried to change the index and texture coordinates, that didn't work. but I think your problem is exactly in your 2D to 3D coordinate mapping.
90 degree rotation is expected with current mapped coordination you shared. I mean :
0.5f, 0.5f, 0.0f -> 0.0f, 0.0f
0.5f, -0.5f, 0.0f -> 1.0f, 0.0f
-0.5f, -0.5f, 0.0f -> 1.0f, 1.0f
-0.5f, 0.5f, 0.0f -> 0.0f, 1.0f
If you don't want the 90 degree rotation it should be :
0.5f, 0.5f, 0.0f -> 0.0f, 0.0f
0.5f, -0.5f, 0.0f -> 1.0f, 0.0f
-0.5f, -0.5f, 0.0f -> 0.0f, 1.0f
-0.5f, 0.5f, 0.0f -> 1.0f, 1.0f
So your mesh should be like this (didn't swap the colors, change it if you need):
Mesh mesh = {
// Position Color Texture coordinates
// X Y Z R G B X Y
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.0f,
// Index
0, 1, 2,
2, 3, 0
};
EDITED
I have a script that I am unable to make fully 3D. So far on ortho the background shows up only. In perspective, almost nothing shows up but when I move the camera it does change color.
projection = glm::perspective(glm::radians(44.0f), static_cast<GLfloat>(Width) / static_cast<GLfloat>(Height), 0.1f, 100.0f);
projection = glm::ortho(0.0f, static_cast<GLfloat>(Width), static_cast<GLfloat>(Height), 0.0f, -1.0f, 1.0f);
See below for images:
Image 1:
3D version - Ortho
Image 2:
3D version - Ortho
Image 3:
2D version - Stable and works perfectly
Here is my code that creates and renders sprites:
#ifndef SPRITE_H
#define SPRITE_H
#include <GL/glew.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "ShaderClass.h"
#include "TextureClass.h"
class Sprite
{
public:
Shader shader;
// Set up Vertex Array Object && Vertex Buffer Object
GLuint VAO,
VBO;
// Constructor
Sprite(Shader &shader){ this->shader = shader; setBuffers(); }
// Deconstructor
~Sprite(){ glDeleteVertexArrays(1, &VAO); }
// Initializes and configures the buffers and vertex attributes
void setBuffers()
{
// Define vertices for the sprite
GLfloat vertices[] = {
// x y z u v
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 1.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
//
// OpenGL buffers
// Initialization code using Vertex Array Object (VAO) (done once (unless the object frequently changes))
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
// Copy our vertices array in a buffer for OpenGL to use
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Bind Vertex Array Object
glBindVertexArray(VAO);
//Attributes
glEnableVertexAttribArray(0); // location = 0
glVertexAttribPointer(
0, // location = 0
3, // 3 components (x, y, z)
GL_FLOAT, GL_FALSE,
5 * sizeof(GLfloat), // stride: 5 * float (x, y, z, u, v)
(GLvoid*)0); // offset: 0
glEnableVertexAttribArray(1); // location = 1
glVertexAttribPointer(
1, // location = 1
2, // 2 components (u, v)
GL_FLOAT, GL_FALSE,
5 * sizeof(GLfloat), // stride: 5 * float (x, y, z, u, v)
(GLvoid*)(3 * sizeof(GLfloat))); // offset: 3 * float (x, y, z)
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//Unbind the VAO
glBindVertexArray(0);
}
// Renders the sprite
void DrawSprite(Texture &texture, glm::vec2 position, glm::vec2 size = glm::vec2(10, 10), GLfloat rotate = 0.0f, glm::vec3 colour = glm::vec3(1.0f))
{
// Apply the shader
this->shader.Use();
// Transform the object
glm::mat4 transformObject;
transformObject = glm::translate(transformObject, glm::vec3(position, 0.0f));
transformObject = glm::translate(transformObject, glm::vec3(0.5f * size.x, 0.5f * size.y, 0.0f));
transformObject = glm::rotate(transformObject, rotate, glm::vec3(0.0f, 0.0f, 1.0f));
transformObject = glm::translate(transformObject, glm::vec3(-0.5f * size.x, -0.5f * size.y, 0.0f));
transformObject = glm::scale(transformObject, glm::vec3(size, 1.0f));
this->shader.SetVector3f("spriteColour", colour);
this->shader.SetMatrix4("transformObject", transformObject);
glActiveTexture(GL_TEXTURE0);
// Bind the appropriate texture to *this* model
texture.Bind();
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36 * 5);
glBindVertexArray(0);
}
};
#endif
These are the shaders that I am using:
Vertex shader:
#version 440 core
layout (location = 0) in vec3 Position;
layout (location = 1) in vec2 texCoord;
out vec2 TexCoords;
uniform mat4 transformObject;
uniform mat4 view;
uniform mat4 projection;
void main()
{
TexCoords = vec2(texCoord.x, texCoord.y);
gl_Position = projection * view * transformObject * vec4(Position.x, Position.y, Position.z, 1.0);
}
Fragment shader:
#version 440 core
in vec2 TexCoords;
out vec4 colour;
uniform sampler2D tex;
uniform vec3 spriteColour;
void main()
{
colour = vec4(spriteColour, 1.0) * texture(tex, TexCoords);
}
I am trying to make a skybox with cube mapping using 6 textures. Out of all the cube map textures that I have used only 1 set of 6 textures works fine. I am not sure what is causing the problem.
This is how I am doing it:
-Creating the CubeMap texture ID
glGenTextures(1, &m_texHandle);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_texHandle);
for(int i = 0; i < 6; ++i)
{
//create image/pixel buffer
TextureLoader tex = TextureLoader(fileNames[i].c_str(), extension);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, tex.GetWidth(), tex.GetHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, tex.GetBuffer());
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
-Initialize and Rendering code
void MeshData::InitializeSkyBox()
{
GLfloat 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
};
m_indicieCount = 36;
// Allocate an OpenGL vertex array object.
glGenVertexArrays(1, &m_vertexArrayID);
// Bind the vertex array object to store all the buffers and vertex attributes we create here.
glBindVertexArray(m_vertexArrayID);
// Generate an ID for the vertex buffer.
glGenBuffers(1, &m_vertexBufferID);
// Bind the vertex buffer and load the vertex position data into the vertex buffer.
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, m_indicieCount * 3 * sizeof(float), &skyboxVertices[0], GL_STREAM_DRAW);
// Enable the two vertex array attributes.
glEnableVertexAttribArray(0); // Vertex position.
// Specify the location and format of the position portion of the vertex buffer.
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferID);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
}
void MeshData::Render()
{
//set cubemap texture for shader
m_shader->SetShaderSampler("shaderTexture", 0, TextureManager::GetInstance()->GetTexture("skyBox"));
glBindVertexArray(m_vertexArrayID);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferID);
glDrawArrays(GL_TRIANGLES, 0, m_indicieCount);
glBindVertexArray(0);
}
The SetShaderSampler function:
bool Shader::SetShaderSampler(const char* name, int slot, TextureLoader* texture)
{
if(texture == NULL)
{
cout << "Shader::SetShaderSampler setting a null texture" << endl;
return true;
}
int loc = glGetUniformLocation(m_shaderProgram, name);
if(loc >= 0)
{
glActiveTexture(GL_TEXTURE0 + slot);
GLenum type = (texture->GetTextureType() == TextureLoader::CUBE_MAP_TGA) ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
glBindTexture(type, texture->GetHandle());
glUniform1i(loc, slot);
}
return true;
}
-Shader code
////////////////////////////////////////////////////////////////////////////////
// Filename: cubeMap.vs
////////////////////////////////////////////////////////////////////////////////
#version 400
/////////////////////
// INPUT VARIABLES //
/////////////////////
layout(location = 0)in vec3 inputPosition;
//////////////////////
// OUTPUT VARIABLES //
//////////////////////
out vec3 texCoord;
///////////////////////
// UNIFORM VARIABLES //
///////////////////////
uniform mat4 worldMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
////////////////////////////////////////////////////////////////////////////////
// Vertex Shader
////////////////////////////////////////////////////////////////////////////////
void main(void)
{
// Calculate the position of the vertex against the view, and projection matrices.
mat4 mv = projectionMatrix * mat4(mat3(viewMatrix));
gl_Position = mv * vec4(inputPosition, 1.0);
texCoord = inputPosition;
}
////////////////////////////////////////////////////////////////////////////////
// Filename: cubeMap.ps
////////////////////////////////////////////////////////////////////////////////
#version 400
/////////////////////
// INPUT VARIABLES //
/////////////////////
in vec3 texCoord;
//////////////////////
// OUTPUT VARIABLES //
//////////////////////
out vec4 outputColor;
///////////////////////
// UNIFORM VARIABLES //
///////////////////////
uniform samplerCube shaderTexture;
////////////////////////////////////////////////////////////////////////////////
// Pixel Shader
////////////////////////////////////////////////////////////////////////////////
void main(void)
{
outputColor = texture(shaderTexture, texCoord);
}
-Results I get
This is the only set of cube map textures that works for me
Now here is where the issue comes in. I have tried a lot of different sets of textures and either it displays nothing or I get the issue below.
This is the original skybox cube map set of 6 textures
But when I play the game, it displays lines like this one
So any insights as to why this is happening? I believe that I am doing something wrong since out of most of the textures I have tried only one works.
Dumb mistake on my part but the solution to my problem was that I had an alpha channel on the texture. Once I removed the alpha channel, it worked correctly!
I'm attempting to implement a skybox in a game. The image I am using is:
Unfortunately, it is extremely magnified, only showing a few of the pixels of the texture. It looks like this:
here's my code for creating the skybox:
SkyBox::SkyBox()
{
programID = LoadShaders("Resources/Shaders/skybox.vert", "Resources/Shaders/skybox.frag");
pID = glGetUniformLocation(programID, "P");
vID = glGetUniformLocation(programID, "V");
float points[] =
{
-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
};
glGenBuffers (1, &vbo);
glBindBuffer (GL_ARRAY_BUFFER, vbo);
glBufferData (GL_ARRAY_BUFFER, sizeof (points), points, GL_STATIC_DRAW);
const char *pth = "/Users/uonibr/Documents/Programming/Space Shooter/Space Shooter/Space Shooter/Resources/space.jpg";
createCubeMap(pth, pth, pth, pth, pth, pth);
}
bool load_cube_map_side (GLuint texture, GLenum side_target, const char* file_name)
{
glBindTexture (GL_TEXTURE_CUBE_MAP, texture);
int x, y;
unsigned char* image_data = SOIL_load_image(file_name, &x, &y, 0, SOIL_LOAD_RGBA);
if (!image_data) {
fprintf (stderr, "ERROR: could not load %s\n", file_name);
return false;
}
// non-power-of-2 dimensions check
if ((x & (x - 1)) != 0 || (y & (y - 1)) != 0) {
fprintf (
stderr, "WARNING: image %s is not power-of-2 dimensions\n", file_name
);
}
// copy image data into 'target' side of cube map
glTexImage2D (
side_target,
0,
GL_RGBA,
x,
y,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
image_data
);
free (image_data);
return true;
}
void SkyBox::createCubeMap ( const char* front, const char* back, const char* top, const char* bottom, const char* left,const char* right)
{
// generate a cube-map texture to hold all the sides
glActiveTexture (GL_TEXTURE0);
glGenTextures (1, &cubeMap);
// load each image and copy into a side of the cube-map texture
assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, front));
assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, back));
assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, top));
assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, bottom));
assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, left));
assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_POSITIVE_X, right));
// format cube map texture
glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
and here's the rendering code for the skybox:
void SkyBox::render(const Camera &camera) const
{
glDepthMask (GL_FALSE);
glUseProgram (programID);
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_CUBE_MAP, cubeMap);
glUniformMatrix4fv(pID, 1, GL_FALSE, &camera.getProjectionMatrix()[0][0]);
glm::mat4 view = camera.getRotationMatrix();
glUniformMatrix4fv(vID, 1, GL_FALSE, &view[0][0]);
glEnableVertexAttribArray (0);
// 1st attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
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
);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glDrawArrays (GL_TRIANGLES, 0, 36);
glDisableVertexAttribArray(0);
glDepthMask (GL_TRUE);
glCullFace(GL_BACK);
}
the fragment shader is simple:
#version 330 core
in vec3 texcoords;
uniform samplerCube cube_texture;
out vec4 frag_color;
void main () {
frag_color = texture (cube_texture, texcoords);
}
as is the vertex shader:
#version 330 core
in vec3 vp;
uniform mat4 P, V;
out vec3 texcoords;
void main () {
texcoords = vp;
gl_Position = P * V * vec4 (vp, 1.0);
}
EDIT:
here's my code for producing the projection matrix:
glm::mat4 Camera::getProjectionMatrix() const
{
return glm::perspective(FoV, 4.0f / 3.0f, 0.1f, 100.0f);
}
and here is my FoV:
float FoV = 3.14159 * 65. / 180;
I determined the issue:
I was passing radians into the glm::perspective() function when I should have passed degrees. Therefore, as was commented on the question, the answer was a small FoV
I'm trying to draw a cube with an FBO texture. The texture is rendered to correctly (which I can see in gDebugger), but it doesn't render on the cube. I thought that this might be a problem with the FBO texture so I loaded an ordinary texture and tried it as well, but I get the same problem, just a black cube.
Stepping through the program in gDebugger, I can see that the texture is both loaded correctly and bound, but nothing is drawn. There also doesn't seem to be any problems with the texcoords. Note that I've also tried to output a solid color in the fragment shader which works correctly.
This is my vertex shader:
#version 420
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
layout(location = 0) in vec3 vertex;
layout(location = 1) in vec2 texcoord;
out vec2 f_texcoord;
void main() {
gl_Position = projection * view * model * vec4(vertex, 1.0);
f_texcoord = texcoord;
}
And this is my fragment shader:
#version 420
uniform sampler2D tex;
in vec2 f_texcoord;
out vec4 gl_FragColor;
void main() {
gl_FragColor = texture2D(tex, f_texcoord);
}
And this is where I draw the cube:
ShaderManager::Get("world")->Use();
glBindVertexArray(cube_vao);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindTexture(GL_TEXTURE_2D, 0);
glBindVertexArray(0);
I must be blind, because I see no errors.
(Also, please note that I am using SFML and GLEW for context creation and extensions.)
EDIT:
I don't know if this will be helpful, but this is how I set up the cube VBO, uniforms, etc.:
glClearColor(1.0, 0.0, 0.0, 1.0);
glEnable(GL_DEPTH_TEST);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
sf::Image img;
img.LoadFromFile("test.png");
img.FlipVertically();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.GetWidth(), img.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, img.GetPixelsPtr());
glBindTexture(GL_TEXTURE_2D, 0);
ShaderTime = 0.0;
camz = -4.0f;
rotation_y = 0.0f;
Shader* shader = ShaderManager::Load("shader", "fx.vert", "fx.frag");
Shader* world = ShaderManager::Load("world", "world.vert", "world.frag");
shader->Use();
glUniform1f(glGetUniformLocation(shader->GetId(), "time"), ShaderTime);
world->Use();
glm::mat4 proj = glm::perspective(60.0f, (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, 0.1f, 1000.0f);
glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, camz));
glm::mat4 model;
glUniformMatrix4fv(glGetUniformLocation(world->GetId(), "projection"), 1, GL_FALSE, glm::value_ptr(proj));
glUniformMatrix4fv(glGetUniformLocation(world->GetId(), "view"), 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(glGetUniformLocation(world->GetId(), "model"), 1, GL_FALSE, glm::value_ptr(model));
glUniform1i(glGetUniformLocation(world->GetId(), "tex"), 0);
glGenVertexArrays(1, &cube_vao);
glBindVertexArray(cube_vao);
glGenBuffers(1, &cube_vbo);
glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);
GLfloat* data = new GLfloat[5 * 36] {
// Front
-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f,
// Back
-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f,
// Top
-1.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, 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, 0.0f, 1.0f,
// Bottom
-1.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, 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, 0.0f, 1.0f,
// Left
-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f,
// Right
1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f
};
glBufferData(GL_ARRAY_BUFFER, (5 * 36) * sizeof(GLfloat), data, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLvoid*)(0));
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLvoid*)(sizeof(GLfloat) * 3));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
===EDIT===
It looks like you're missing the texture setup for the minification filter, which is a problem if you're not using a mipmapped texture. See here: http://www.opengl.org/wiki/Common_Mistakes#Creating_a_complete_texture