Related
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,
};
I'm creating a voxel game and want to highlight the block that the camera is pointing at with a wireframe model. However, I can't for the life of me figure out why this isn't showing up. I've set the position of the model to a static location.
renderer:
constexpr std::array<float, 72> VERTICES =
{
0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
0.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 0.0f
};
constexpr std::array<int, 24> INDICES =
{
0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15,
16, 17, 18, 19,
20, 21, 22, 23
};
SelectedBlockRenderer::SelectedBlockRenderer():
should_render(false),
shader("shader/selectedBlockVertexShader.txt", "shader/selectedBlockFragmentShader.txt")
{
shader.set_uniforms({"position", "projectionView"});
glGenVertexArrays(1, &vao_id);
glGenBuffers(1, &v_buffer_id);
glGenBuffers(1, &i_buffer_id);
glBindVertexArray(vao_id);
glBindBuffer(GL_ARRAY_BUFFER, v_buffer_id);
glBufferData(GL_ARRAY_BUFFER, sizeof(VERTICES), &VERTICES[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, nullptr);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer_id);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(INDICES), &INDICES[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
SelectedBlockRenderer::~SelectedBlockRenderer()
{
}
void SelectedBlockRenderer::render(const Display& display, const Camera& camera)
{
if (!should_render) return;
glDisable(GL_CULL_FACE);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glLineWidth(10.0f);
glm::mat4 projection_view = display.get_projection_matrix() * camera.get_view();
shader.activate();
shader.load_uniform("projectionView", projection_view);
shader.load_uniform("position", glm::vec3(x, y, z));
glBindVertexArray(vao_id);
glEnableVertexAttribArray(0);
glDrawElements(GL_QUADS, INDICES.size(), GL_UNSIGNED_INT, nullptr);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
shader.deactivate();
glEnable(GL_CULL_FACE);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
void SelectedBlockRenderer::free()
{
shader.free();
glDeleteBuffers(1, &v_buffer_id);
glDeleteBuffers(1, &i_buffer_id);
glDeleteVertexArrays(1, &vao_id);
}
Shader code:
#version 400 core
layout(location = 0) in vec3 vertex;
uniform mat4 projectionView;
uniform vec3 position;
void main () {
gl_Position = projectionView * vec4(position, 1.0);
}
Fragment shader:
#version 400 core
out vec4 fragment;
void main () {
fragment = vec4(0.0, 0.0, 0.0, 1.0);
}
I know that the Shader class works because I've used it in all of the other renderers. Here's the relevant main.cpp code:
void main () {
SelectedBlockRenderer sb_renderer;
while(!display.closed) {
if (timer.update_requested) {
//update display and camera
sb_renderer.render(display, camera);
}
}
sb_renderer.free();
}
If any other code is required I'd be happy to share it.
I must be missing something really obvious. If anyone has any idea I'd love to hear it.
position is a uniform variable. The name of the vertex coordinate attribute is vertex.
The position of the current vertex (gl_Position) should be set by a function of the vertex coordinate. e.g.:
gl_Position = projectionView * vec4(vertex, 1.0);
or
gl_Position = projectionView * vec4(vertex + position, 1.0);
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;
}
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 run my first OpenGL program. In the main() function I have infinity loop:
do {
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(programID);
_collection[0].draw();
_collection[1].draw();
glfwSwapBuffers(window);
glfwPollEvents();
} while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0)
The function _collection[].draw() should draw rectangles:
static const GLfloat g_vertex_buffer_data[] = {
x, y, 0.0f, // lewy górny
x, y - 0.4f, 0.0f, // lewy dolny
x + 0.4f, y - 0.4f, 0.0f, // prawy dolny
x + 0.4f, y, 0.0f, // lewy górny
x + 0.02f, y - 0.02f, 0.0f, // lewy górny
x + 0.02f, y - 0.4f + 0.02f, 0.0f, // lewy dolny
x + 0.4f - 0.02f, y - 0.4f + 0.02f, 0.0f, // prawy dolny
x + 0.4f - 0.02f, y - 0.02f, 0.0f, // lewy górny
};
static const GLfloat g_color_buffer_data[] = {
1.0f, 1.0f, 1.0f, // lewy górny
1.0f, 1.0f, 1.0f, // lewy dolny
1.0f, 1.0f, 1.0f, // prawy dolny
1.0f, 1.0f, 1.0f, // lewy górny
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
};
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 colorbuffer;
glGenBuffers(1, &colorbuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);
glEnableVertexAttribArray(vertexPosition_modelspaceID);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
vertexPosition_modelspaceID, // The attribute we want to configure
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// przekazuję kolory wierzchołków
glEnableVertexAttribArray(vertexColorID);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glVertexAttribPointer(
vertexColorID, // The attribute we want to configure
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// rysuję wszystko
glDrawArrays(GL_QUADS, 0, 8);
glDisableVertexAttribArray(vertexPosition_modelspaceID);
glDisableVertexAttribArray(vertexColorID);
My problem is that: When I run the program I see only the effect of a run the first function draw() - this with index 0. Then I change places these functions:
_collection[1].draw();
_collection[0].draw();
I still see the effect of the first function - in this case with index number 1.
It looks like there is something blocking the code from the second draw() function to run.
What is the problem? How can I fix it?
The second draw function isn't being blocked from executing. Since your vertice and color information is defined as static inside the body of your draw() function, those values won't change regardless of which element of _collection you are drawing. That's why drawing the two collections yields the same result -- you are drawing your vertices in the same location, and with the same colors.
To fix the problem, you only want to store vertex and color information once. Each of your collections should only contain x and y values, indicating their position. You don't want multiple collections of vertices and colors, you want a single collection of vertices and colors which you draw in several different locations.
You should create your vertex and color arrays in your main function before you enter your main loop. You should also use glGenBuffers and glBindBuffer followed by glBufferData to tell OpenGL about your vertex and color arrays in your main program before your main loop as well. Then you can take the calls to glGenBuffers and glBufferData out of your draw function. You should also call glVertexAttribPointer for both the vertex and color arrays in your main function and remove them from your draw() function.
// Note that your vertex data isn't contingent on 'x' and 'y' positions.
// You will use the vertex shader to move your boxes around later.
GLfloat g_vertex_buffer_data[] = {
0.0f, 0, 0.0f, // lewy górny
0.0f, 0.4f, 0.0f, // lewy dolny
0.4f, 0.4f, 0.0f, // prawy dolny
0.4f, 0.0f, 0.0f, // lewy górny
0.02f, 0.02f, 0.0f, // lewy górny
0.02f, 0.4f + 0.02f, 0.0f, // lewy dolny
0.4f - 0.02f, 0.4f + 0.02f, 0.0f, // prawy dolny
0.4f - 0.02f, 0.02f, 0.0f, // lewy górny
};
GLfloat g_color_buffer_data[] = {
1.0f, 1.0f, 1.0f, // lewy górny
1.0f, 1.0f, 1.0f, // lewy dolny
1.0f, 1.0f, 1.0f, // prawy dolny
1.0f, 1.0f, 1.0f, // lewy górny
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
};
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);
glVertexAttribPointer(
vertexPosition_modelspaceID, // The attribute we want to configure
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
GLuint colorbuffer;
glGenBuffers(1, &colorbuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);
glVertexAttribPointer(
vertexColorID, // The attribute we want to configure
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// All of the above information you only need to specify to openGL once, not every time you draw a frame!
You need to change your shader so that it accepts the x and y offset from each of your collections:
#version 150
uniform float collectionX;
uniform float collectionY;
in vec3 vertexPosition_modelspaceID; // This is the vertex attribute which the name 'vertexPosition_modelspaceID' corresponds to.
// Remember that your shader will also accept a color and give it to the fragment shader, include that code as well.
void main()
{
gl_Position = vec4(vertexPosition_modelspaceID.x + collectionX, vertexPosition_modelspaceID.y + collectionY, vertexPosition_modelspaceID.z, 1.0);
}
And you need to get the locations of the uniform variables you just added to your shader in your main program before the loop:
// Call these functions after you compile and link your shaders. programID should be your compiled and linked shader program.
GLuint collectionXID = glGetUniformLocation(programID, "collectionX");
GLuint collectionYID = glGetUniformLocation(programID, "collectionY");
Your draw function will be very simple now:
void draw()
{
glDrawArrays(GL_QUADS, 0, 8);
}
Finally, your main loop will look something like this:
do
{
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(programID);
glEnableVertexAttribArray(vertexPosition_modelspaceID);
glEnableVertexAttribArray(vertexColorID);
glUniform1f(collectionXID, _collection[0].x);
glUniform1f(collectionYID, _collection[0].y);
_collection[0].draw();
glUniform1f(collectionXID, _collection[1].x);
glUniform1f(collectionYID, _collection[1].y);
_collection[1].draw();
glfwSwapBuffers(window);
glDisableVertexAttribArray(vertexPosition_modelspaceID);
glDisableVertexAttribArray(vertexColorID);
glfwPollEvents();
} while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0)
Note that you are now specifying the location at which to draw the vertices to your shader program by passing your individual collection's x and y position with the glUniform1f function. It is more common to move your vertices around with a transformation matrix, but that is a rather complicated topic itself.
Assuming the collections have different x and y positions, they will now draw in different locations.