array of sampler2D uses last bound texture [duplicate] - c++

This question already has answers here:
Will any of the following texture lookups cause undefined behavior, non-uniform flow, or both?
(1 answer)
Why are Uniform variables not working in GLSL?
(1 answer)
Closed 10 months ago.
I am trying to implement a simple batchrenderer. I am using an array of sampler2D for it. however, the array is using the last bound texture instead of using the texture bound to the texture unit. I would really appreciate if anyone can help me out. here's my code:
Edit: the sampler2d array index is working fine. when i used FragColor = vec4(t, 0, 0, 0); it gave me a black quad and a red quad. But for some, it is using the last bound texture. both the quads are using texture2.
main.cpp
int main()
{
Window window("DJROXZHIA", 800, 600, true);
Shader shader("res/shaders/vertex.glsl", "res/shaders/fragment.glsl");
shader.enable();
float vertices[] = {
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, -0.5f, 0.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, 1.0f, 1.0f, 1.0f,
-0.5f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f
};
unsigned int indices[] = {
0, 1, 2, 2, 3, 0,
4, 5, 6, 6, 7, 4
};
Texture texture("res/texture/DodgerCover.png");
Texture texture2("res/texture/game-play-image.png"); //both the quads are using texture2
GLuint vao, vbo, ibo;
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glGenBuffers(1, &ibo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(DJROXZHIA::maths::Vertex2D), (void*)offsetof(DJROXZHIA::maths::Vertex2D, pos));
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, sizeof(DJROXZHIA::maths::Vertex2D), (void*)offsetof(DJROXZHIA::maths::Vertex2D, texture));
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(DJROXZHIA::maths::Vertex2D), (void*)offsetof(DJROXZHIA::maths::Vertex2D, texCoords));
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(DJROXZHIA::maths::Vertex2D), (void*)offsetof(DJROXZHIA::maths::Vertex2D, color));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
GLfloat t[2] = { 0.0f, 1.0f };
glUniform1fv(glGetUniformLocation(shader.getID(), "u_texture"), 2, t);
while (!window.closed())
{
window.clear(glm::vec4(0.0f));
glActiveTexture(GL_TEXTURE + 0);
glBindTexture(GL_TEXTURE_2D, texture.getTextureID());
glActiveTexture(GL_TEXTURE + 1);
glBindTexture(GL_TEXTURE_2D, texture2.getTextureID());
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
window.tick();
}
return 0;
}
vertex.glsl
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in float aTexture;
layout (location = 2) in vec2 aTexCoords;
layout (location = 3) in vec4 aColor;
out float tex;
out vec2 texCoords;
out vec4 color;
out vec3 pos;
//uniform mat4 u_ProjView;
void main()
{
gl_Position = vec4(aPos, 1.0);
tex = aTexture;
texCoords = aTexCoords;
color = aColor;
pos = aPos;
}
fragment.glsl
#version 330 core
in float tex;
in vec2 texCoords;
in vec4 color;
in vec3 pos;
uniform sampler2D u_texture[2];
out vec4 FragColor;
void main()
{
int t = int(tex);
FragColor = texture(u_texture[t], texCoords) * color;
}
Thanks in advance

Related

how to warp texture in openGL? (Perspective correction?)

I wanna make the OpenGL program can present images and warp the images presented.
Although I achieved image rendering using OpenGL, I don't know how to warp an image.
An warpable example I want is (Reference):
But a picture I got is:
As I know, this problem is related to perspective correction mapping.
But I don't know about that well.
Here is my source code.
void imageRender(Shader initShader, Shader imgShader, char *path){
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
float positions = { 0.5f, 1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
-1.0f, 1.0f, 0.0f };
float vertices[] = {
// positions // colors // texture coords
position[0], position[1], position[2], 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right
position[3], position[4], position[5], 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right
position[6], position[7], position[8], 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom left
position[9], position[10],position[11], 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
};
unsigned int indices[] = {
0, 1, 3,
1, 2, 3
};
unsigned int VAO, VBO, EBO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// position attribute
//glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
// color attribute
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(2);
//texture attribute
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(3);
FREE_IMAGE_FORMAT format = FreeImage_GetFileType(path, 0);
if (format == -1){
cerr << BOLDRED << "[ERROR] IMAGE_NOT_FOUND" << RESET << endl;
exit(1);
}
if (format == FIF_UNKNOWN){
cerr << BOLDRED << "[ERROR] UNKNOWN_IMAGE_FORMAT" << RESET << endl;
format = FreeImage_GetFIFFromFilename(path);
if (!FreeImage_FIFSupportsReading(format)){
cerr << BOLDRED << "[ERROR] IMAGE_FORMAT_NOT_READABLE" << RESET << endl;
exit(1);
}
}
FIBITMAP *bitmap = FreeImage_Load(format, path);
FIBITMAP *bitmap32;
int bitsPerPixel = FreeImage_GetBPP(bitmap);
bitmap32 = FreeImage_ConvertTo32Bits(bitmap);
int imageWidth = FreeImage_GetWidth(bitmap32);
int imageHeight = FreeImage_GetHeight(bitmap32);
GLubyte *textureData = FreeImage_GetBits(bitmap32);
GLuint texture1;
glGenTextures(1, &texture1);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageWidth, imageHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, textureData);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
initShader.use();
glBindVertexArray(VAO);
int initalTime = time(NULL);
while(1){
glBindVertexArray(VAO);
int timecal = time(NULL);
//glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_INT, 0);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
if ((timecal - initalTime) > imageTime) // imageTime value is 10
break;
}
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glDeleteTextures(1, &texture1);// image
glDisable(GL_TEXTURE_2D);//image
FreeImage_Unload(bitmap32);
FreeImage_Unload(bitmap);
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
}
}
Shader code is like that
//shader.vs
#version 330 core
layout(location = 1) in vec3 position;
layout(location = 2) in vec3 color;
layout(location = 3) in vec2 texcoord;
out vec3 Color;
out vec2 Texcoord;
void main()
{
gl_Position = vec4(position, 1.0);
Texcoord = texcoord;
}
//shader.fs
#version 330 core
in vec3 Color;
in vec2 Texcoord;
out vec4 outColor;
uniform sampler2D texture5;
void main()
{
outColor = texture2D(texture5, Texcoord);
}
How can I warp texture?
And then Is it correct to use position value to warp texture image?
The issue has nothing to do with perspective projection. You draw a polygon with 4 vertices parallel to the XY plane of the view, but the polygon is not a quad! Change the x coordinate of the 1st vertex (0.5f -> 1.0f). Perspective projection works with Homogeneous coordinates.
In generalperspective projection is achieved by a Perspective projection matrix. Of course you can define homogeneous vertices to inspect the behavior:
Define an attribute tuple with homogenous vertices (4 components):
float vertices[] = {
// positions // colors // texture coords
1.0f, 1.0f, 0.5f, 2.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right
1.0f, -1.0f, -0.5f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right
-1.0f, -1.0f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom left
-1.0f, 1.0f, 0.5f, 2.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
};
Adapt the vertex specification and the vertex shader:
// position attribute
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
// color attribute
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void*)(4 * sizeof(float)));
glEnableVertexAttribArray(2);
//texture attribute
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void*)(7 * sizeof(float)));
glEnableVertexAttribArray(3);
#version 330 core
layout(location = 1) in vec4 position;
layout(location = 2) in vec3 color;
layout(location = 3) in vec2 texcoord;
out vec3 Color;
out vec2 Texcoord;
void main()
{
gl_Position = position;
Texcoord = texcoord;
}
Another option to achieve the effect is, to a an Z component to the geometry. e.g:
float positions = { 1.0f, 1.0f, 0.5f,
1.0f, -1.0f, 0.0f,
-1.0f, -1.0f, -0.5f,
-1.0f, 1.0f, 0.0f };
and to compute the w component dependent on z in the vertex shader (e.g. w = z + 2.5:
#version 330 core
layout(location = 1) in vec3 position;
layout(location = 2) in vec3 color;
layout(location = 3) in vec2 texcoord;
out vec3 Color;
out vec2 Texcoord;
void main()
{
gl_Position = vec4(position, position.z + 2.5);
Texcoord = texcoord;
}

Wireframe cube rendering blank in OpenGL

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);

OpenGL rendering black square

I am attempting to render a colored rectangle, but I just end up with a black one.
My shaders and shader program do not produce any errors when compiling or linking, so I am sure there is something going wrong when I am attempting to buffer the data. But, everything looks correct to me.
Shader sources
std::string const fragment_shader_source = "#version 330 core\n"
""
"in vec4 fColor;\n"
"\n"
"out vec4 finalColor;\n"
"\n"
"void main() {\n"
" finalColor = fColor;\n"
"}";
std::string const vertex_shader_source = "#version 330 core\n"
""
"layout (location = 0) in vec2 vPos;\n"
"layout (location = 1) in vec4 vColor;\n"
"\n"
"out vec4 fColor;\n"
"void main() {\n"
" gl_Position = vec4(vPos.xy, 1.0, 1.0);\n"
" fColor = vColor;\n"
"}";
Vertex data
static GLfloat const vertex_data[] = {
// //Position //Color //UV Coords
0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f
};
Here is my main loop:
int SDLApp::AppMain(int argc, char** argv) {
if(sdl_window_ == nullptr) {
acorn::Log(acorn::LoggingLevel::Fatal, "Could not initialize the window.");
return -1;
}
if(sdl_gl_context_ == nullptr) {
acorn::Log(acorn::LoggingLevel::Fatal, "Could not create an OpenGL context.");
return -1;
}
acorn::shader::FragmentShader f(fragment_shader_source);
acorn::shader::VertexShader v(vertex_shader_source);
acorn::shader::Program shader_program(f, v);
shader_program.Link();
shader_program.Use();
GLuint vao_;
glGenVertexArrays(1, &vao_);
GLuint vbo_;
glGenBuffers(1, &vbo_);
glBindVertexArray(vao_);
glBindBuffer(GL_ARRAY_BUFFER, vbo_);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)2);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(GLfloat) * 6, vertex_data, GL_STATIC_DRAW);
glClearColor(1.0f, 0.0f, 0.0f,1.0f);
SDL_Event event;
while (true) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
return 0;
}
}
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 6);
SDL_GL_SwapWindow(sdl_window_);
}
}
The last parameter of glVertexAttribPointer is treated as a byte offset into the buffer object's data store.
So the offset has to be 8, 2*sizeof(float):
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat),
(void*)(2*sizeof(GLfloat)));
After changing that, your code works fine

SegFault after calling glDrawArrays

I am attempting to write a sprite batcher.
Originally, I was uploading the following data to openGL in order to see if I could get anything to the screen:
static GLfloat const vertexData[] = {
//Position //Color //UV Coords
0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f
};
These are my Vertex and Fragment Shaders:
const char* vert = "#version 330 core\n"
"layout (location = 0) in vec2 vPos;\n"
"layout (location = 1) in vec4 vColor;\n"
"layout (location = 2) in vec2 vTexPos;\n"
"\n"
"out vec4 fColor;\n"
"out vec2 fTexPos;\n"
"\n"
"void main() {\n"
" gl_Position = vec4(vPos.xy, 0.0, 1.0);\n"
" fColor = vColor;\n"
" fTexPos = vec2(vTexPos.s, 1.0 - vTexPos.t);\n"
"}";
const char* frag = "#version 330 core\n"
"in vec4 fColor;\n"
"in vec2 fTexPos;\n"
"out vec4 finalColor;\n"
"\n"
"uniform sampler2D textureUniform;\n"
"\n"
"void main() {\n"
" vec4 textureColor = texture(textureUniform, fTexPos);"
" finalColor = fColor * textureColor;\n"
"}";
I set up the VAO and VBO like so:
auto vaoID_ = 0;
auto vboID_ = 0;
glGenVertexArrays(1, &vaoID_);
glGenBuffers(1, &vboID_);
glBindVertexArray(vaoID_);
glBindBuffer(GL_ARRAY_BUFFER, vboID_);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 8, (void*)0); // Screen Position
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 8, (void*)(2 *sizeof(GL_FLOAT)); //Color
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8, (void*)(6 * sizeof(GL_FLOAT)); //UV
And finally, on each loop, I would orphan the buffer and then sub the data in.
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), nullptr, GL_DYNAMIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertexData), vertexData);
glDrawArrays(GL_TRIANGLES, 0, 6);
This worked fine!
So, I attempted to begin to write a basic sprite batch.
I grouped my vertex data into a POD struct:
struct VertexData {
struct {
GLfloat screenx;
GLfloat screeny;
} position;
struct {
GLfloat r;
GLfloat g;
GLfloat b;
GLfloat a;
} color;
struct {
GLfloat texu;
GLfloat texv;
} uv;
}
And used a vector to batch everything together:
std::vector<VertexData> spritebatch_
I changed the calls to glVertexAttribPointer to match this struct (although I think this change was unneeded?)
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, position)); // Screen Position
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, color)); //Color
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, uv)); //UV
To test it, on every loop I would feed it the same data that was in the static GLfloat array:
spritebatch_.push_back({0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f});
spritebatch_.push_back({-0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f});
spritebatch_.push_back({0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f});
spritebatch_.push_back({-0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f});
spritebatch_.push_back({-0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f});
spritebatch_.push_back({0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f});
And then attempt to orphan the buffer and sub the data in:
glBufferData(GL_VERTEX_ARRAY, spritebatch_.size() * sizeof(VertexData), nullptr, GL_DYNAMIC_DRAW);
glBufferSubData(GL_VERTEX_ARRAY, 0, spritebatch_.size() * sizeof(VertexData), spritebatch_.data());
glDrawArrays(GL_TRIANGLES, 0, spritebatch_.size());
Finally, I would reset the spritebatch_: spritebatch_.clear();
However, this segfaults. Am I doing something incorrect when I go to orphan the buffer and sub the data in? The data formats still match (VertexData POD members are all GLfloats still), the size of spritebatch_ is still 6 (6 vertices to make a square), and the location of that data is still the same within each vertex.
The 5th parameter of glVertexAttribPointer is the "stride", the byte offset between consecutive generic vertex attributes.
So the change from
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 8, (void*)0); // Screen Position
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 8, (void*)(2 *sizeof(GL_FLOAT)); //Color
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8, (void*)(6 * sizeof(GL_FLOAT)); //UV
to
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, position)); // Screen Position
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, color)); //Color
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, uv)); //UV
is important, because sizeof(VertexData) is not 8, but it is 8*sizeof(GL_FLOAT) .
The first parameter of glBufferData respectively glBufferSubData has to be the enumerator constant for the target, which is one of GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER, ... .
GL_VERTEX_ARRAY identifies the vertex array for the fixed function client-side capability - See glEnableClientState.
Change:
glBufferData(GL_VERTEX_ARRAY, ...);
glBufferData(GL_ARRAY_BUFFER, ...);
glBufferSubData(GL_VERTEX_ARRAY, ...);
glBufferSubData(GL_ARRAY_BUFFER, ...);
Note, if you would check for OpenGL errors (glGetError or Debug Output), you would get a GL_INVALID_ENUM error.
The data store for the array buffer is not created, this causes the segment fault.

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;
}