Texture mapping on cube only shows two sides correctly - c++

I tried to make a cube in openGL and render a default texture on each side. I've been messing around with it for days but I cant get it to work. I really don't know what the problem is as I am convinced that my vertices and texture coordinates are right. What am I doing wrong?
These are my vertices, uv's and indices:
vertices = {
// front face
0.0f, 0.0f, 0.0f,
length, 0.0f, 0.0f,
length, height, 0.0f,
0.0f, height, 0.0f,
// back face
0.0f, 0.0f, width,
length, 0.0f, width,
length, height, width,
0.0f, height, width,
// left face
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, width,
0.0f, height, width,
0.0f, height, 0.0f,
// right face
length, 0.0f, 0.0f,
length, 0.0f, width,
length, height, width,
length, height, 0.0f,
// top face
0.0f, height, 0.0f,
length, height, 0.0f,
length, height, width,
0.0f, height, width,
// bottom face
0.0f, 0.0f, 0.0f,
length, 0.0f, 0.0f,
length, 0.0f, width,
0.0f, 0.0f, width
};
uvs = {
// front face
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
// back face
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
// left face
0.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f,
0.0f, 1.0f,
// right face
1.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
1.0f, 1.0f,
// top face
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 1.0f,
0.0f, 1.0f,
// bottom face
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 0.0f,
0.0f, 0.0f
};
indices = {
// front face
0, 1, 2,
2, 3, 0,
// right face
1, 5, 6,
6, 2, 1,
// back face
7, 6, 5,
5, 4, 7,
// left face
4, 0, 3,
3, 7, 4,
// bottom face
4, 5, 1,
1, 0, 4,
// top face
3, 2, 6,
6, 7, 3
};
This is my render method:
void Mesh::render() {
// Render the pyramid using OpenGL
view = glm::lookAt(Camera::getInstance().cameraPos, Camera::getInstance().cameraPos + Camera::getInstance().cameraFront, Camera::getInstance().cameraUp);
mvp = projection * view * model;
// Attach to program_id
glUseProgram(programId);
// Send mvp
glUniformMatrix4fv(uniformMvp, 1, GL_FALSE, glm::value_ptr(mvp));
// Send vao
glBindVertexArray(vao);
glBindTexture(GL_TEXTURE_2D, textureId);
glDrawElements(GL_TRIANGLES, indices.size() * sizeof(GLushort),
GL_UNSIGNED_SHORT, 0);
glBindVertexArray(0);
}
Vertexshader:
#version 430 core
in vec2 UV;
uniform sampler2D texsampler;
layout(location = 0) out vec4 gl_FragColor;
void main()
{
// Compute the diffuse and specular components for each fragment
vec3 test = texture2D(texsampler, UV).rgb;
// Write final color to the framebuffer
gl_FragColor = vec4(test, 1.0);
}
and the fragmentshader:
#version 430 core
// Uniform matrices
uniform mat4 mv;
uniform mat4 projection;
// Per-vertex inputs
in vec3 position;
// UV
in vec2 uv;
out vec2 UV;
void main()
{
// Calculate view-space coordinate
vec4 P = mv * vec4(position, 1.0);
// Calculate the clip-space position of each vertex
gl_Position = projection * P;
UV = uv;
}
Image of the cube:
I think this is enough information. Only the front and the back are textured normally and the rest is just like on the image.

Your texture coordinates are wrong, as commented:
// left face
0.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f,
0.0f, 1.0f,
// right face
1.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
1.0f, 1.0f,
This tells the computer to take a single line of pixels and stretch them across the entire face. The U coordinate is the same for the whole face. It does not advance from left to right across the texture.
Same for the top and bottom faces:
// top face
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 1.0f,
0.0f, 1.0f,
// bottom face
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 0.0f,
0.0f, 0.0f
the V does not advance, so the computer keeps reading the first or last row of the texture over and over. If you want to use the entire texture, then V should be 0 on one side of the texture, and 1 on the other side. Also note the direction where U changes must be different than the direction V changes - i.e. they can't change together - or else the compute only reads the diagonal pixels where U and V are equal.

Looking at OPs vertices, I noticed that there are 24 of them although a cube has 8 corners only. That's not surprising as coordinates for the same corner may correspond to distinct vertex coordinates depending on which face it belongs to.
Hence, it makes sense to define coordinates and corresponding texture coordinates per face, i.e. 6 faces with 4 corners each face -> 24 coordinates.
I enriched OPs code with enumeration:
vertices = {
// front face
0.0f, 0.0f, 0.0f, // 0
length, 0.0f, 0.0f, // 1
length, height, 0.0f, // 2
0.0f, height, 0.0f, // 3
// back face
0.0f, 0.0f, width, // 4
length, 0.0f, width, // 5
length, height, width, // 6
0.0f, height, width, // 7
// left face
0.0f, 0.0f, 0.0f, // 8
0.0f, 0.0f, width, // 9
0.0f, height, width, // 10
0.0f, height, 0.0f, // 11
// right face
length, 0.0f, 0.0f, // 12
length, 0.0f, width, // 13
length, height, width, // 14
length, height, 0.0f, // 15
// top face
0.0f, height, 0.0f, // 16
length, height, 0.0f, // 17
length, height, width, // 18
0.0f, height, width, // 29
// bottom face
0.0f, 0.0f, 0.0f, // 20
length, 0.0f, 0.0f, // 21
length, 0.0f, width, // 22
0.0f, 0.0f, width // 23
};
uvs = {
// front face
0.0f, 0.0f, // 0
1.0f, 0.0f, // 1
1.0f, 1.0f, // 2
0.0f, 1.0f, // 3
// back face
0.0f, 0.0f, // 4
1.0f, 0.0f, // 5
1.0f, 1.0f, // 6
0.0f, 1.0f, // 7
// left face
0.0f, 0.0f, // 8
0.0f, 0.0f, // 9
0.0f, 1.0f, // 10
0.0f, 1.0f, // 11
// right face
1.0f, 0.0f, // 12
1.0f, 0.0f, // 13
1.0f, 1.0f, // 14
1.0f, 1.0f, // 15
// top face
0.0f, 1.0f, // 16
1.0f, 1.0f, // 17
1.0f, 1.0f, // 18
0.0f, 1.0f, // 29
// bottom face
0.0f, 0.0f, // 20
1.0f, 0.0f, // 21
1.0f, 0.0f, // 22
0.0f, 0.0f // 23
};
But then I took a closer look what the indices look-up:
indices = {
// ...
// right face
1, 5, 6, // -> UV: { 1.0f, 0.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f }
6, 2, 1, // -> UV: { 1.0f, 1.0f }, { 1.0f, 1.0f }, { 1.0f, 0.0f }
// ...
}
There are only two distinct values of texture coordinates but there should be four of them. Hence, it's not a surprise if the texture projection of that right face looks strange.
OP noted the wrong indices. This doesn't manifest in the geometry as the wrong indices address coordinates (vertices) with identical values. However, concerning the texture coordinates (uvs) these indices are just wrong.
According to the added index values, I corrected the indices for the right face:
indices = {
// ...
// right face
12, 13, 14,
14, 15, 12,
// ...
}
The indices of the top face are defined correctly but the other faces have to be checked as well. (I leave this as "homework" to OP. Or, like a colleague of mine used to say: Not to punish just to practice.) ;-)
On the second glance, I realized that OP's texture coordinates are wrong as well.
To understand how texture coordinates work:
There is a uv coordinate system applied to the image with
(0, 0) … the lower left corner
(1, 0) … the lower right corner
(0, 1) … the upper left corner
of the image.
taken from opengl-tutorial – Tutorial 5: A Textured Cube
Hence, using my
uvs = {
// ...
// right face
1.0f, 0.0f, // 12
1.0f, 0.0f, // 13
1.0f, 1.0f, // 14
1.0f, 1.0f, // 15
// ...
};
provides two times the lower right corner and two times the upper right corner. The result of such texture projection are stripes instead of bricks.
A better result should be achieved by repeating the texture coordinates of the front face 6 times:
uvs = {
// ...
// right face
0.0f, 0.0f, // 12
1.0f, 0.0f, // 13
1.0f, 1.0f, // 14
0.0f, 1.0f, // 15
// ...
};

Related

OpenGL - Going 3D

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

OpenGL Color By Face

I'm new to OpenGL and theres a small project I'm working on. A part of this project is create a grid which allows for some sections of the grid to have different colors.
E.g. The entire grid is green but a block on the grid is lit red and maybe another one yellow.
What I have done to draw this grid is with GL_TRIANGLE_STRIP while using indicies. After that stage, I have also included colors in the same vertex data array. But the output isn't how i want it to be.
Firstly there was an interpolation which i tried to remove by adding the 'flat' flag for the color. But there seem to be a overlapping problem. Which resulted this picture.
Is there anyway to create a grid. Where a block of the grid can be of a different color than the grid.
Update
Here is my code for GL_TRIANGLES
short* Grid::Indicies()
{
const int X_GRID_SIZE = X_GRID_SIZE_;
const int Y_GRID_SIZE = Y_GRID_SIZE_;
const int INDICIES_SIZE = (((X_GRID_SIZE * 4) + ((X_GRID_SIZE_ - 3) * 2)) * Y_GRID_SIZE);
short* indicies = new short[INDICIES_SIZE];
int index = 0;
for (size_t y = 0; y < Y_GRID_SIZE_; y++)
{
// Current, Down, Right, Down
indicies[index++] = (short)(y * X_GRID_SIZE_);
indicies[index++] = (short)((y + 1) * X_GRID_SIZE_);
indicies[index++] = (short)((y * X_GRID_SIZE_) + 1);
indicies[index++] = (short)((y + 1) * X_GRID_SIZE_);
for (size_t x = 1; x < X_GRID_SIZE_ - 1; x++)
{
// Current, Down, Current, Down, Right, Down
for (size_t i = 0; i < 2; i++)
{
indicies[index++] = (short)((y * X_GRID_SIZE_) + x);
indicies[index++] = (short)(((y + 1) * X_GRID_SIZE_) + x);
}
indicies[index++] = (short)((y * X_GRID_SIZE_) + x + 1);
indicies[index++] = (short)(((y + 1) * X_GRID_SIZE_) + x);
}
// Current, Down
indicies[index++] = (short)(((y + 1) * X_GRID_SIZE_) - 1);
indicies[index++] = (short)(((y + 2) * X_GRID_SIZE_) - 1);
}
indicies_size_ = index;
return (indicies);
}
GLfloat vertices[] = {
// Position // Color
-1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-0.5f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-1.0f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f,
1.0f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
};
GLuint v_buffer_object, v_array_object, e_buffer_object;
glGenVertexArrays(1, &v_array_object);
glGenBuffers(1, &v_buffer_object);
glGenBuffers(1, &e_buffer_object);
glBindVertexArray(v_array_object);
glBindBuffer(GL_ARRAY_BUFFER, v_buffer_object);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, e_buffer_object);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(grid.Indicies()) * grid.IndiciesSize(), grid.Indicies(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
Don't use GL_TRIANGLE_STRIP. Use GL_TRIANGLES and draw each block with 2 triangles and 4 vertices. Each vertex belongs to only 1 block. Thanks to that you don't have to use 'flat' flag, just change color for 4 vertices at once. You can try to draw each block separate, with space between each other. Then you can connect them by translating vertices and create the grid.
With GL_TRIANGLE_STRIP, flat shading will use the color from vertex i+2 to color traingle i (this is called the provoking vertex). This doesn't get you what you want. An easy option is to switch to GL_TRIANGLES, and make sure to specify your element indexes so that the same vertex is chosen third for both triangles in each quad (because the third vertex is the provoking vertex for triangles, by default). For example, suppose these are the vertexes:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
Let's look at one of the quads:
0---1
| |
4---5
Let's choose vertex 0 to hold the color for the entire quad. What we then do is make sure that both triangles include vertex 0, and that vertex 0 is last in both triangles.
0---1
| \ |
4---5
So our index array will be:
5 1 0 4 5 0 ...
This uses positive (anticlockwise) winding order.

GDI+: How to replace black pixels with red pixels?

I have a black and white image, a would like to replace the black pixels with red pixels. I've tried
Gdiplus::Graphics* g = Gdiplus::Graphics::FromImage(filename);
Gdiplus::ImageAttributes ia;
Gdiplus::ColorMatrix m = {
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
1.0f, 0.0f, 0.0f, 0.0f, 1.0f
};
ia.SetColorMatrix(&m);
g->DrawImage(org, r, 0, 0, org->GetWidth(), org->GetHeight(), Gdiplus::UnitPixel, &ia);
But it's making the entire bitmap red.
Do not use a matrix to perform this transformation. Your matrix will always output the following vector:
[1.0 0.0 0.0 currentAlpha 1.0]
That's why you have a red image.
Visit https://msdn.microsoft.com/en-us/library/ms533875%28v=vs.85%29.aspx
Use this instead
ImageAttributes ia;
ColorMap blackToRed;
blackToRed.oldColor = Color(255, 0, 0, 0); // black
blackToRed.newColor = Color(255, 255, 0, 0);// red
ia.SetRemapTable(1, &blackToRed);

Inproper texture mapping while using QGLBuffer

I wrought basic OpenGL 2.1\ES example for supposed target platform, using Qt 4.7.1 library on Windows. Target is some kind of Linux, with Qt 4.8 max available, no glm or similar libraries. Embedded GPU supports ES 1.0 or OpenGL 2.1 only. Example is "classic" texture cube, which you might met in various OpenGL examples.. but those examples use direct calls to OpenGL functions, what isn't available to me for lack of proper headers and glew - both on development and on target platforms. Development platform is Windows 7.
Geometry
static const int vertexDataCount = 6 * 4 * 4;
static const float vertexData[vertexDataCount] = {
// Left face
-0.5f, -0.5f, -0.5f, 1.0f,//0
-0.5f, -0.5f, 0.5f, 1.0f,//1
-0.5f, 0.5f, 0.5f, 1.0f,//2
-0.5f, 0.5f, -0.5f, 1.0f,//3
// Top face
-0.5f, 0.5f, -0.5f, 1.0f, //4
-0.5f, 0.5f, 0.5f, 1.0f, //5
0.5f, 0.5f, 0.5f, 1.0f, //6
0.5f, 0.5f, -0.5f, 1.0f, //7
// Right face
0.5f, 0.5f, -0.5f, 1.0f,//8
0.5f, 0.5f, 0.5f, 1.0f,//9
0.5f, -0.5f, 0.5f, 1.0f,//10
0.5f, -0.5f, -0.5f, 1.0f,//11
// Bottom face
0.5f, -0.5f, -0.5f, 1.0f,//12
0.5f, -0.5f, 0.5f, 1.0f,//13
-0.5f, -0.5f, 0.5f, 1.0f,//14
-0.5f, -0.5f, -0.5f, 1.0f,//15
// Front face
0.5f, -0.5f, 0.5f, 1.0f,//16/
0.5f, 0.5f, 0.5f, 1.0f,//17
-0.5f, 0.5f, 0.5f, 1.0f,//18
-0.5f, -0.5f, 0.5f, 1.0f,//19
// Back face
0.5f, 0.5f, -0.5f, 1.0f,//20
0.5f, -0.5f, -0.5f, 1.0f,//21
-0.5f, -0.5f, -0.5f, 1.0f,//22
-0.5f, 0.5f, -0.5f, 1.0f //23
};
// Normal vectors
static const int normalDataCount = 6 * 4 * 3;
static const float normalData[normalDataCount] = {
// Left face
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
// Top face
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
// Right face
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
// Bottom face
0.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
// Front face
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
// Back face
0.0f, 0.0f, -1.0f,
0.0f, 0.0f, -1.0f,
0.0f, 0.0f, -1.0f,
0.0f, 0.0f, -1.0f
};
// Texure coords
static const int textureCoordDataCount = 6 * 4 * 2;
static const float textureCoordData[textureCoordDataCount] = {
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f
};
// Indices
//
// 3 indices per triangle
// 2 triangles per face
// 6 faces
static const int indexDataCount = 6 * 3 * 2;
static const unsigned int indexData[indexDataCount] = {
0, 1, 2, 0, 2, 3, // Left face
4, 5, 6, 4, 6, 7, // Top face
8, 9, 10, 8, 10, 11, // Right face
12, 14, 15, 12, 13, 14, // Bottom face
16, 17, 18, 16, 18, 19, // Front face
20, 22, 23, 20, 21, 22 // Back face
};
This is how I load texture
glEnable(GL_TEXTURE_2D);
m_texture = bindTexture(QImage("cube.png"));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
if(m_shaderProgram)
m_shaderProgram->setUniformValue("texture", 0); // texture unit 0, assuming that we used
Vertex shader
#version 120
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
attribute vec4 vertex;
attribute vec3 normal;
attribute vec2 texturecoord;
varying vec3 fragmentNormal;
varying vec2 outtexture;
void main( void )
{
// Transform the normal vector
fragmentNormal = ( modelViewMatrix * vec4( normal, 0.0 ) ).xyz;
// Calculate the clip-space coordinates
gl_Position = projectionMatrix * modelViewMatrix * vertex;
outtexture = texturecoord;
}
Fragment shader
#version 120
// in
uniform sampler2D texture;
varying vec2 outtexture;
varying vec3 fragmentNormal;
// out
// gl_FragColor
void main( void )
{
// Calculate intensity as max of 0 and dot product of the
// fragmentNormal and the eye position (0,0,1).
float intensity;
intensity = max( dot( fragmentNormal, vec3( 0.0, 0.0, 1.0 ) ), 0.15 );
gl_FragColor = intensity * texture2D(texture,outtexture); // vec4( 1.0, 0.0, 0.0, 1.0 );
}
I bind buffers this way (prepareBufferObject is little snippet function I took from Qt sample):
// Prepare the vertex, normal and index buffers
m_vertexBuffer = new QGLBuffer(QGLBuffer::VertexBuffer );
if ( !prepareBufferObject( m_vertexBuffer, QGLBuffer::StaticDraw, vertexData, sizeof(vertexData) ) )
return;
m_normalBuffer = new QGLBuffer(QGLBuffer::VertexBuffer );
if ( !prepareBufferObject( m_normalBuffer, QGLBuffer::StaticDraw, normalData, sizeof(normalData) ) )
return;
m_texBuffer = new QGLBuffer(QGLBuffer::IndexBuffer );
if ( !prepareBufferObject( m_texBuffer, QGLBuffer::StaticDraw, textureCoordData, sizeof(textureCoordData) ) )
return;
m_indexBuffer = new QGLBuffer(QGLBuffer::IndexBuffer );
if ( !prepareBufferObject( m_indexBuffer, QGLBuffer::StaticDraw, indexData, sizeof(indexData) ) )
return;
loadShaders("vertexshader120.glsl", "fragshader120.glsl");
// Enable the "vertex" attribute to bind it to our vertex buffer
m_vertexBuffer->bind();
m_shaderProgram->setAttributeBuffer( "vertex", GL_FLOAT, 0, 4 ); //xyzw
m_shaderProgram->enableAttributeArray( "vertex" );
// Enable the "normal" attribute to bind it to our texture coords buffer
m_normalBuffer->bind();
m_shaderProgram->setAttributeBuffer( "normal", GL_FLOAT, 0, 3 ); //xyz
m_shaderProgram->enableAttributeArray( "normal" );
m_texBuffer->bind();
m_shaderProgram->setAttributeBuffer( "texturecoord", GL_FLOAT, 0, 2 ); //uv
m_shaderProgram->enableAttributeArray( "texturecoord" );
// Bind the index buffer ready for drawing
m_indexBuffer->bind();
Finally , paintGL method
void GWidget::paintGL()
{
QMatrix4x4 model;
model.setToIdentity();
model.rotate(m_rotation);
QMatrix4x4 mv = m_view * model;
// MVP = projection * view * model
// uploading MVP into shader (may add code to check if MVP was update since last redraw)
m_shaderProgram->setUniformValue("modelViewMatrix",mv);
m_shaderProgram->setUniformValue("projectionMatrix",m_projection);
// set up to render the scene
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw stuff
glDrawElements( GL_TRIANGLES, // Type of primitive to draw
indexDataCount, // The number of indices in our index buffer we wish to draw
GL_UNSIGNED_INT, // The element type of the index buffer
0 ); // Offset from the start of our index buffer of where to begin
}
Everything works except texture looks misaligned and skewed -both on development and on target platforms. I checked UVs and that they correspond to proper vertices - yet it looks like order of texture coordinates is wrong. Where is error here?
For reference: source code
This is my first attempt at usage of flexible pipeline, so I could do something dumb there.
You're setting up your texture coordinate buffer as an index buffer:
m_texBuffer = new QGLBuffer(QGLBuffer::IndexBuffer );
Since it contains vertex attribute data, it should be created as:
m_texBuffer = new QGLBuffer(QGLBuffer::VertexBuffer);

DirectX when I add a texture to a quad the triangles mess up somehow, fix?

First of all here are the important parts of my code.
Creating the vertices.
D3DVertexTexture Vertices[] =
{
{-1.0f, 1.0f, 0.0f, 0.0f, 0.0f, },
{ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, },
{ 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, },
{-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, },
};
Creating the vertex buffer.
D3DDevice->CreateVertexBuffer(sizeof(Vertices),
0,
D3DFVF_CUSTOMVERTEXTEXTURE,
D3DPOOL_MANAGED,
&vb,
NULL);
Memory crap.
void* pVoid;
vb->Lock(0, sizeof(pVoid), (void**) &pVoid, 0);
memcpy(pVoid, Vertices, sizeof(Vertices));
vb->Unlock();
Loading the texture.
D3DXCreateTextureFromFile(D3DDevice, "images/tex.png", &t);
Rendering.
D3DDevice->SetFVF(D3DFVF_CUSTOMVERTEXTEXTURE);
D3DDevice->SetTexture(0, t);
D3DDevice->SetStreamSource(0, vb, 0, sizeof(D3DVertexTexture));
D3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
Where is my problem.
It shows a square but the left side of the side is missing in a triangular shape like this.
Vertices A,B,C,D in a triangle strip will produce two triangles: A,B,C and B,C,D
A -- B A--B B
| | \ | /|
| | \| / |
D -- C C D--C
Look at that diagram and picture those two triangles...
Then go and put your vertices in the right order - triangle strips should 'zig-zag', not proceed in clockwise or anti-clockwise order.
If you order them: A,B,D,C - the quad will draw correctly.
Have you tried defining you vertices in this order:
D3DVertexTexture Vertices[] =
{
{ 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, 0.0f, },
{ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, },
};
I believe the order in wich vertices are drawn is by default the clockwise order. You are defining in an incorrect order.