Applying textures to indexed primitives. C++ DX9 - c++

I have a basic program that draws a cube out of 48 tetrahedrons. More precisely it uses 27 vertices and an index buffer to draw these tetrahedrons. I would like to apply a texture to all of the tetrahedrons but all of the tutorials I found about textures don't render using indices and every vertex in my program is used in 16 other tetrahedrons so i can't even figure out how to orient the textures. The program itself is too long and too messy for me to post it but If someone could please tell me whether it's possible to put textures onto indexed primitives or not and also give me a link to a tutorial I would be grateful.
EDIT: Code ici:
void setVertices(FLOAT cubeYOffset, FLOAT cubeXOffset, FLOAT cubeZOffset, int tetraRender[]){
CUSTOMVERTEX vertices[] = {
{ cubeXOffset+1.0f, cubeYOffset+0.0f, cubeZOffset-1.0f, 0.0f, 0.5f, 0.0f, 0.0f, 1.0f, },//Center top = 0
{ cubeXOffset+0.0f, cubeYOffset+0.0f, cubeZOffset-1.0f, -0.5f, 0.5f, 0.0f, -1.0f, 1.0f, },
{ cubeXOffset+0.0f, cubeYOffset+0.0f, cubeZOffset+0.0f, -0.5f, 0.5f, 0.5f, -1.0f, 1.0f, },
{ cubeXOffset+1.0f, cubeYOffset+0.0f, cubeZOffset+0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 1.0f, },
{ cubeXOffset+2.0f, cubeYOffset+0.0f, cubeZOffset+0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, },
{ cubeXOffset+2.0f, cubeYOffset+0.0f, cubeZOffset-1.0f, 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, },
{ cubeXOffset+2.0f, cubeYOffset+0.0f, cubeZOffset-2.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, },
{ cubeXOffset+1.0f, cubeYOffset+0.0f, cubeZOffset-2.0f, 0.0f, 0.5f, -0.5f, 0.0f, 1.0f, },
{ cubeXOffset+0.0f, cubeYOffset+0.0f, cubeZOffset-2.0f, -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, },
{ cubeXOffset+1.0f, cubeYOffset-1.0f, cubeZOffset-1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, },//Center middle = 9
{ cubeXOffset+0.0f, cubeYOffset-1.0f, cubeZOffset-1.0f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, },
{ cubeXOffset+0.0f, cubeYOffset-1.0f, cubeZOffset+0.0f, -0.5f, 0.0f, 0.5f, -1.0f, 0.0f, },
{ cubeXOffset+1.0f, cubeYOffset-1.0f, cubeZOffset+0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, },
{ cubeXOffset+2.0f, cubeYOffset-1.0f, cubeZOffset+0.0f, 0.5f, 0.0f, 0.5f, 1.0f, 0.0f, },
{ cubeXOffset+2.0f, cubeYOffset-1.0f, cubeZOffset-1.0f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, },
{ cubeXOffset+2.0f, cubeYOffset-1.0f, cubeZOffset-2.0f, 0.5f, 0.0f, -0.5f, 1.0f, 0.0f, },
{ cubeXOffset+1.0f, cubeYOffset-1.0f, cubeZOffset-2.0f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, },
{ cubeXOffset+0.0f, cubeYOffset-1.0f, cubeZOffset-2.0f, -0.5f, 0.0f, -0.5f, -1.0f, 0.0f, },
{ cubeXOffset+1.0f, cubeYOffset-2.0f, cubeZOffset-1.0f, 0.0f, -0.5f, 0.0f, 0.0f, -1.0f, },//Center bottom = 18
{ cubeXOffset+0.0f, cubeYOffset-2.0f, cubeZOffset-1.0f, -0.5f, -0.5f, 0.0f, -1.0f, -1.0f, },
{ cubeXOffset+0.0f, cubeYOffset-2.0f, cubeZOffset+0.0f, -0.5f, -0.5f, 0.5f, -1.0f, -1.0f, },
{ cubeXOffset+1.0f, cubeYOffset-2.0f, cubeZOffset+0.0f, 0.0f, -0.5f, 0.5f, 0.0f, -1.0f, },
{ cubeXOffset+2.0f, cubeYOffset-2.0f, cubeZOffset+0.0f, 0.5f, -0.5f, 0.5f, 1.0f, -1.0f, },
{ cubeXOffset+2.0f, cubeYOffset-2.0f, cubeZOffset-1.0f, 0.5f, -0.5f, 0.0f, 1.0f, -1.0f, },
{ cubeXOffset+2.0f, cubeYOffset-2.0f, cubeZOffset-2.0f, 0.5f, -0.5f, -0.5f, 1.0f, -1.0f, },
{ cubeXOffset+1.0f, cubeYOffset-2.0f, cubeZOffset-2.0f, 0.0f, -0.5f, -0.5f, 0.0f, -1.0f, },
{ cubeXOffset+0.0f, cubeYOffset-2.0f, cubeZOffset-2.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, },//26(actually 27th)
};
d3ddev->CreateVertexBuffer(27*sizeof(CUSTOMVERTEX),
0,
CUSTOMFVF,
D3DPOOL_MANAGED,
&v_buffer,
NULL);
VOID* pVoid;
v_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, vertices, sizeof(vertices));
v_buffer->Unlock();
short tetra[48][12] = {
//tetra 1
0, 1, 2,
0, 1, 11,
0, 2, 11,
1, 2, 11,
//tetro 2
0, 2, 3,
0, 2, 11,
0 , 3, 11,
2, 3, 11,
//tetro 3
0, 3, 4,
0, 3, 13,
0, 4, 13,
3, 4, 13,
//tetro 4
0, 4, 5,
0, 4, 13,
0, 5, 13,
4, 5, 13,
//tetro 5
0, 5, 6,
0, 5, 15,
0, 6, 15,
5, 6, 15,
//tetro 6
0, 6, 7,
0, 6, 15,
0, 7, 15,
6, 7, 15,
//tetro 7
0, 7, 8,
0, 7, 17,
0, 8, 17,
7, 8, 17,
//tetro 8
0, 8, 1,
0, 8, 17,
0, 1, 17,
8, 1, 17,
//tetro 9
0, 1, 11,
0, 1, 10,
0, 10, 11,
1, 10, 11,
//tetro 10
0, 3, 11,
0, 3, 12,
0, 11, 12,
3, 11, 12,
//tetro 11
0, 3, 13,
0, 3, 12,
0, 12, 13,
3, 12, 13,
//tetro 12
0, 5, 13,
0, 5, 14,
0, 13, 14,
5, 13, 14,
//tetro 13
0, 5, 15,
0, 5, 14,
0, 14, 15,
5, 14, 15,
//tetro 14
0, 7, 15,
0, 7, 16,
0, 15, 16,
7, 15, 16,
//tetro 15
0, 7, 17,
0, 7, 16,
0, 16, 17,
7, 16, 17,
//tetro 16
0, 1, 17,
0, 1, 10,
0, 17, 10,
1, 17, 10,
//tetro 17
0, 10, 11,
0, 9, 10,
0, 9, 11,
9, 10, 11,
//tetro 18
0, 11, 12,
0, 9, 11,
0, 9, 12,
9, 11, 12,
//tetro 19
0, 12, 13,
0, 9, 12,
0, 9, 13,
9, 12, 13,
//tetro 20
0, 13, 14,
0, 9, 13,
0, 9, 14,
9, 13, 14,
//tetro 21
0, 14, 15,
0, 9, 14,
0, 9, 15,
9, 14, 15,
//tetro 22
0, 15, 16,
0, 9, 15,
0, 9, 16,
9, 15, 16,
//tetro 23
0, 16, 17,
0, 9, 16,
0, 9, 17,
9, 16, 17,
//tetro 24
0, 17, 10,
0, 9, 17,
0, 9, 10,
9, 17, 10,
//tetro 17
9, 10, 11,
9, 18, 10,
9, 18, 11,
18, 10, 11,
//tetro 18
9, 11, 12,
9, 18, 11,
9, 18, 12,
18, 11, 12,
//tetro 19
9, 12, 13,
9, 18, 12,
9, 18, 13,
18, 12, 13,
//tetro 20
9, 13, 14,
9, 18, 13,
9, 18, 14,
18, 13, 14,
//tetro 21
9, 14, 15,
9, 18, 14,
9, 18, 15,
18, 14, 15,
//tetro 22
9, 15, 16,
9, 18, 15,
9, 18, 16,
18, 15, 16,
//tetro 23
9, 16, 17,
9, 18, 16,
9, 18, 17,
18, 16, 17,
//tetro 24
9, 17, 10,
9, 18, 17,
9, 18, 10,
18, 17, 10,
//tetro 9
18, 19, 11,
18, 19, 10,
18, 10, 11,
19, 10, 11,
//tetro 10
18, 21, 11,
18, 21, 12,
18, 11, 12,
21, 11, 12,
//tetro 11
18, 21, 13,
18, 21, 12,
18, 12, 13,
21, 12, 13,
//tetro 12
18, 23, 13,
18, 23, 14,
18, 13, 14,
23, 13, 14,
//tetro 13
18, 23, 15,
18, 23, 14,
18, 14, 15,
23, 14, 15,
//tetro 14
18, 25, 15,
18, 25, 16,
18, 15, 16,
25, 15, 16,
//tetro 15
18, 25, 17,
18, 25, 16,
18, 16, 17,
25, 16, 17,
//tetro 16
18, 19, 17,
18, 19, 10,
18, 17, 10,
19, 17, 10,
//tetro 19
18, 19, 20,
18, 19, 11,
18, 20, 11,
19, 20, 11,
//tetro 20
18, 20, 21,
18, 20, 11,
18 , 21, 11,
20, 21, 11,
//tetro 21
18, 21, 22,
18, 21, 13,
18, 22, 13,
21, 22, 13,
//tetro 22
18, 22, 23,
18, 22, 13,
18, 23, 13,
22, 23, 13,
//tetro 23
18, 23, 24,
18, 23, 15,
18, 24, 15,
23, 24, 15,
//tetro 24
18, 24, 25,
18, 24, 15,
18, 25, 15,
24, 25, 15,
//tetro 25
18, 25, 26,
18, 25, 17,
18, 26, 17,
25, 26, 17,
//tetro 26
18, 26, 19,
18, 26, 17,
18, 19, 17,
26, 19, 17,
};
short indices [576];
int i = 0;
int i2 = 0;
ind = 0;
int ic;
for(i; i < 48; i++){
if (tetraRender[i] == 1){
for(i2; i2 < 12; i2++){
if((ind == 0)&&(i2 == 0)){
ic = 0;
}else{
ic = ind*12+i2;
}
indices[ic] = tetra[i][i2];
}
i2 = 0;
ind++;
}
}
if (ind > 0) {
d3ddev->CreateIndexBuffer(12*ind*sizeof(short),
0,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&i_buffer,
NULL);
i_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, indices, 12*ind*2);
i_buffer->Unlock();
}
}
Ok so thats the declaration of the vertices and indices just to give you an idea. Its very messy so I'm sorry and if you can't see what it does is declare a spiral-like set of vertices followed by the declaration of all of the indices of the tetrahedrons. then it uses the int array in the from the function to draw only specified tetrahedrons.
And yes I am using 3D lighting even though I haven't the fainest why.

You're not supposed to use the FVF system anymore. Use the IDirect3DVertexDeclaration9 system, which is far more actually flexible. The problem with FVF is that when you set the flags together, the order is unspecifiable, whereas the VERTEXELEMENT9[] system is capable of specifying the order of elements as well as which ones are contained within.
The simple answer of how to generate the texture co-ordinates is pretty simple- when you consider a vertex, then it's position in 3D space and thus ultimately it's texture co-ordinates are fixed, regardless of which triangle it actually ends up a part of. Thus, unless you intend to emulate some very sharp edges, in which case you should duplicate vertices, it's perfectly acceptable to have one tex-coord per vertex with no more effort.
As for rendering the system without crashing, then it's time to use a shader, basically because fixed-function is dead and almost all modern rendering uses shaders, and you have to have learned this stuff a long time ago to know how to use it. Fortunately, basic texturing is basic and won't require anything particularly advanced.
D3DVERTEXELEMENT9 vertexDecl[] = {
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
{ 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
D3DDECL_END()
};
struct CustomVertex {
float position[3];
float normal[3];
float texcoords[2];
};
IDirect3DVertexDeclaration9* vertexdecl;
d3ddev->CreateVertexDeclaration(vertexDecl, &vertexdecl);
And as for the shader, then something pretty simple will do.
// Stuff we send to the shader from C++
// This is not per-vertex. Anything we loaded into the
// vertex data itself is input to the vertex shader.
// Direct3D 9.0c also supports hardware instancing, but I'll
// leave you to work that one out yourself.
// World * View * Projection matrix gives the result in Homogenous Clip
// Co-ordinates, which is what Direct3D wants from us as output
uniform extern float4x4 WVPMatrix;
// WorldInverseTranspose transforms the normal into world space
// successfully, even with non-linear transformations as the World
uniform extern float4x4 WorldInverseTransposeMatrix;
// This is just a 2D texture that we can change at any time
uniform extern texture MyTexture;
// The sampler state determines how the texture is filtered.
sampler TexS = sampler_state
{
Texture = <MyTexture>;
MinFilter = LINEAR;
MagFilter = LINEAR;
};
// What we output from the vertex shader. This is basically the position
// of the vertex in HCC (the first two), and anything we want to pass into
// the pixel shader (the second two).
struct VS_OUTPUT {
float4 position : POSITION0;
float3 normal : NORMAL0;
float2 texcoords : TEXCOORD0;
};
// What we're putting in to the vertex shader. This is basically
// our vertex structure from C++.
struct VS_INPUT {
float3 position : POSITION0;
float3 normal : NORMAL0;
float2 texcoords : TEXCOORD0;
};
VS_OUTPUT VertexShader(VS_INPUT in) {
VS_OUTPUT out = (VS_OUTPUT)0;
// just pass texcoords on, we're not interested
out.texcoords = in.texcoords;
// get the resulting vertex position that we need
out.position = mul(float4(in.position, 1.0f), WVPMatrix);
// transform the normal into world space
out.normal = mul(float4(in.normal, 0.0f), WorldInverseTransposeMatrix).xyz;
}
float4 PixelShader(float3 normal : NORMAL0, float2 texcoords : TEXCOORD0) {
return tex2D(TexS, texcoords);
}
technique BasicShader
{
pass p0
{
vertexShader = compile vs_3_0 VertexShader();
pixelShader = compile ps_3_0 PixelShader();
}
}
I didn't do any lighting calculations here but I did pass the normal into the pixel shader.

I'm by no means a DirectX expert, but speaking out of experience, I assume that it uses an approach very similar to OpenGL.
If you want to texture an object, you need texture coordinates for each vertex, in addition to the position attribute and possibly others (normal, tangent vector, ...).
As you use an index buffer to address vertex data, I assume you have the latter in a vertex buffer. So, by adding texture coordinates to each vertex, you can wrap a texture onto your tetrahedrons. Note however, that you can't have different texture coordinates for each vertex, if your index buffer says 'I want a triangle from index 0, 1 and 2', you will always get both position and texture coordinate data from indices 0, 1, 2.
What you could do is modify the texture coordinates for each tetrahedron as whole, by applying a transformation matrix to them first. This transformation is separate from the transformation you apply to your position attributes.

Related

What are the correct vertices and indices for a cube using this mesh function? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 3 years ago.
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.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
I'm trying to create a cube using vertices and indices. The vertices I found by plotting it onto a graph, and the indices were carefully patterned and calculated to make two triangles per side of a cube. However, when I turned on the program, a cube did not show, why is this? Are my vertices/indices incorrect? Am I putting in the wrong number of vertices/indices in the createMesh function? Or am I doing this all incorrectly?
Function that has indices and vertices.
void createObjects() {
std::vector<GLuint> indices {
//Top
0, 1, 2,
2, 3, 1,
//Bottom
4, 5, 6,
6, 7, 5,
//Front
8, 9, 10,
10, 11, 9,
//Back
12, 13, 14,
14, 15, 13,
//Left
16, 17, 18,
18, 19, 17,
//Right
20, 21, 22,
22, 23, 21
/*0, 3, 1,
1, 3, 2,
2, 3, 0,
0, 1, 2*/
};
std::vector<GLfloat> vertices {
//Top
-1, 1, -1, //0
1, 1, -1 //1
-1, 1, 1, //2
1, 1, 1, //3
//Bottom
-1, -1, -1, //4
1, -1, -1, //5
-1, -1, 1, //6
1, -1, 1 //7
//Front
-1, 1, 1, //8
1, 1, 1, //9
-1, -1, 1, //10
1, -1, 1, //11
//Back
-1, 1, -1, //12
1, 1, -1, //13
-1, -1, -1, //14
1, -1, -1, //15
//Left
-1, 1, 1, //16
-1, 1, -1, //17
-1, -1, 1, //18
-1, -1, -1, //19
//Right
1, 1, 1, //20
1, 1, -1, //21
1, -1, 1, //22
1, -1, -1 //23
/*-1, -1, 0,
0, -1, 1,
1, -1, 0,
0, 1, 0*/
};
for (std::size_t x = 0; x < 2; x++) {
meshVector.emplace_back(new Mesh());
meshVector[x]->createMesh(vertices, indices, 24, 12);
}
}
Create mesh function and draw function
void Mesh::createMesh(const std::vector<GLfloat>& vertices, const std::vector<GLuint>& indices, GLuint numOfVertices, GLuint numOfIndices) {
indexCount = numOfIndices;
//Binding
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
//Information
//VBO Information
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(*vertices.data()) * numOfVertices, vertices.data(), GL_STATIC_DRAW);
//IBO Information
glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(*indices.data()) * numOfIndices, indices.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
//Unbinding
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void Mesh::renderMesh() {
//Binding
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
//Rendering
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0);
//Unbinding
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
Removed GLuint numOfVertices/Indices and replaced sizeof(*vertices.data()) * numOfVertices with sizeof(GLuint) * indices.size()`. Finally, replaced the cube vertices and indices with new coordinates
std::vector<GLuint> indices {
//Top
2, 6, 7,
2, 3, 7,
//Bottom
0, 4, 5,
0, 1, 5,
//Left
0, 2, 6,
0, 4, 6,
//Right
1, 3, 7,
1, 5, 7,
//Front
0, 2, 3,
0, 1, 3,
//Back
4, 6, 7,
4, 5, 7
};
std::vector<GLfloat> vertices {
-1, -1, 0.5, //0
1, -1, 0.5, //1
-1, 1, 0.5, //2
1, 1, 0.5, //3
-1, -1, -0.5, //4
1, -1, -0.5, //5
-1, 1, -0.5, //6
1, 1, -0.5 //7
};
That's it.

Whats the most efficient way of rendering 3D objects in DirectX9 [C++]?

sorry if I'm not specific enough, I'm new to DirectX programming and to Stack Overflow.
The problem is that when I'm rendering 3D objects in DirectX9, I have to manually add the Vertex Buffers and the Index Buffers (draw the cubes by hand). I'm trying to recreate a 'Minecraft' like world but don't know how I would go about it.
I've tried using 'for loops' but that just glitched the entire screen out. I've also attempted using vectors but I just got way to confused and didn't get anywhere.
This is the code I have. As you can see, this is the way I'd draw 2 cubes. I'm wondering if there is another more efficient way since I'd be wanting to draw hundreds of cubes at a time.
void DirectXClass::init_graphics(void)
{
// create the vertices using the CUSTOMVERTEX struct
CUSTOMVERTEX vertices[] =
{
// Square 1
{ 3.0f, 3.0f, -3.0f, D3DCOLOR_XRGB(0, 0, 255), },
{ -3.0f, 3.0f, -3.0f, D3DCOLOR_XRGB(0, 255, 0), },
{ 3.0f, -3.0f, -3.0f, D3DCOLOR_XRGB(255, 0, 0), },
{ -3.0f, -3.0f, -3.0f, D3DCOLOR_XRGB(0, 255, 255), },
{ 3.0f, 3.0f, 3.0f, D3DCOLOR_XRGB(0, 0, 255), },
{ -3.0f, 3.0f, 3.0f, D3DCOLOR_XRGB(255, 0, 0), },
{ 3.0f, -3.0f, 3.0f, D3DCOLOR_XRGB(0, 255, 0), },
{ -3.0f, -3.0f, 3.0f, D3DCOLOR_XRGB(0, 255, 255), },
{ -3.0f, 3.0f, 3.0f, D3DCOLOR_XRGB(0, 0, 255), },
{ 3.0f, 3.0f, 3.0f, D3DCOLOR_XRGB(0, 255, 0), },
{ -3.0f, -3.0f, 3.0f, D3DCOLOR_XRGB(255, 0, 0), },
{ 3.0f, -3.0f, 3.0f, D3DCOLOR_XRGB(0, 255, 255), },
{ -3.0f, 3.0f, 9.0f, D3DCOLOR_XRGB(0, 0, 255), },
{ 3.0f, 3.0f, 9.0f, D3DCOLOR_XRGB(255, 0, 0), },
{ -3.0f, -3.0f, 9.0f, D3DCOLOR_XRGB(0, 255, 0), },
{ 3.0f, -3.0f, 9.0f, D3DCOLOR_XRGB(0, 255, 255), },
};
// create a vertex buffer interface called v_buffer
// d3ddev->CreateVertexBuffer(sizeof(vertices) / sizeof(vertices[0]) * sizeof(CUSTOMVERTEX),
d3ddev->CreateVertexBuffer(sizeof(vertices) / sizeof(vertices[0]) * sizeof(CUSTOMVERTEX),
0,
CUSTOMFVF,
D3DPOOL_MANAGED,
&v_buffer,
NULL);
VOID** pVoid;
// lock v_buffer and load the vertices into it
v_buffer->Lock(0, 0, (void**)& pVoid, 0);
memcpy(pVoid, vertices, sizeof(vertices));
v_buffer->Unlock();
short indices[] =
{
0, 1, 2, // side 1
2, 1, 3,
4, 0, 6, // side 2
6, 0, 2,
7, 5, 6, // side 3
6, 5, 4,
3, 1, 7, // side 4
7, 1, 5,
4, 5, 0, // side 5
0, 5, 1,
3, 7, 2, // side 6
2, 7, 6,
8, 9, 10, // side 9
10, 9, 11,
12, 8, 14, // side 10
14, 8, 10,
15, 13, 14, // side 11
14, 13, 12,
11, 9, 15, // side 12
15, 9, 13,
12, 13, 8, // side 13
8, 13, 9,
11, 15, 10, // side 14
10, 15, 14,
};
// create a vertex buffer interface called v_buffer
// d3ddev->CreateIndexBuffer(sizeof(indices) / sizeof(indices[0]) * sizeof(short),
d3ddev->CreateIndexBuffer(sizeof(indices) / sizeof(indices[0]) * sizeof(short),
0,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&i_buffer,
NULL);
// lock v_buffer and load the vertices into it
i_buffer->Lock(0, 0, (void**)& pVoid, 0);
memcpy(pVoid, indices, sizeof(indices));
i_buffer->Unlock();
}

Stop LibGDX rendering faces inside objects

So by default, libgdx renders both sides of a face. When you make a cube using a mesh (supplying vertices and indices), it renders the faces inside the cube (wasting render time).
I want to stop this because it wastes render time when I have x amount of voxels on the screen.
I have tried face culling but it's completely broken. It removes the sides and everything.
Here's my code:
public void setup() {
String vertexShader = "attribute vec4 a_position; \n" + "attribute vec4 a_color;\n" + "attribute vec2 a_texCoord0;\n" + "uniform mat4 u_projTrans;\n" + "varying vec4 v_color;" + "varying vec2 v_texCoords;" + "void main() \n" + "{ \n" + " v_color = vec4(1, 1, 1, 1); \n" + " v_texCoords = a_texCoord0; \n" + " gl_Position = u_projTrans * a_position; \n" + "} \n";
String fragmentShader = "#ifdef GL_ES\n" + "precision mediump float;\n" + "#endif\n" + "varying vec4 v_color;\n" + "varying vec2 v_texCoords;\n" + "uniform sampler2D u_texture;\n" + "void main() \n" + "{ \n" + " gl_FragColor = v_color * texture2D(u_texture, v_texCoords);\n" + "}";
shader = new ShaderProgram(vertexShader, fragmentShader);
float[] vertices = { -0.5f, 0.5f, -0.5f, 0, 0, -0.5f, -0.5f, -0.5f, 0, 1, 0.5f, -0.5f, -0.5f, 1, 1, 0.5f, 0.5f, -0.5f, 1, 0, -0.5f, 0.5f, 0.5f, 0, 0, -0.5f, -0.5f, 0.5f, 0, 1, 0.5f, -0.5f, 0.5f, 1, 1, 0.5f, 0.5f, 0.5f, 1, 0, 0.5f, 0.5f, -0.5f, 0, 0, 0.5f, -0.5f, -0.5f, 0, 1, 0.5f, -0.5f, 0.5f, 1, 1, 0.5f, 0.5f, 0.5f, 1, 0, -0.5f, 0.5f, -0.5f, 0, 0, -0.5f, -0.5f, -0.5f, 0, 1, -0.5f, -0.5f, 0.5f, 1, 1, -0.5f, 0.5f, 0.5f, 1, 0, -0.5f, 0.5f, 0.5f, 0, 0, -0.5f, 0.5f, -0.5f, 0, 1, 0.5f, 0.5f, -0.5f, 1, 1, 0.5f, 0.5f, 0.5f, 1, 0, -0.5f, -0.5f, 0.5f, 0, 0, -0.5f, -0.5f, -0.5f, 0, 1, 0.5f, -0.5f, -0.5f, 1, 1, 0.5f, -0.5f, 0.5f, 1, 0
};
short[] indices = { 0, 1, 3, 3, 1, 2, 4, 5, 7, 7, 5, 6, 8, 9, 11, 11, 9, 10, 12, 13, 15, 15, 13, 14, 16, 17, 19, 19, 17, 18, 20, 21, 23, 23, 21, 22
};
texture = new Texture("texture.png");
Gdx.input.setCursorCatched(false);
mesh = new Mesh(true, vertices.length / 3, indices.length, VertexAttribute.Position(), VertexAttribute.TexCoords(0));
mesh.setVertices(vertices);
mesh.setIndices(indices);
GL40.glEnable(GL40.GL_DEPTH_TEST);
//GL40.glEnable(GL40.GL_CULL_FACE);
//GL40.glCullFace(GL40.GL_BACK);
}
public void render() {
Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
cameraController.update();
texture.bind();
shader.begin();
shader.setUniformMatrix("u_projTrans", camera.combined);
shader.setUniformi("u_texture", 0);
mesh.render(shader, GL46.GL_TRIANGLES);
shader.end();
}
When Face Culling is enabled then then primitives are discarded, dependent on the winding order of the vertex coordinates, as seen from the point of view.
For this a winding order for the front faces is defined, by glFrontFace. By default this is counter clockwise.
If back faces sculling is enabled:
GL40.glEnable(GL40.GL_CULL_FACE);
GL40.glCullFace(GL40.GL_BACK);
then the polygons which have the opposite winding order (clockwise) are discarded.
According to your vertex coordinates
float[] vertices = {
-0.5f, 0.5f, -0.5f, 0, 0,
-0.5f, -0.5f, -0.5f, 0, 1,
0.5f, -0.5f, -0.5f, 1, 1,
0.5f, 0.5f, -0.5f, 1, 0,
-0.5f, 0.5f, 0.5f, 0, 0,
-0.5f, -0.5f, 0.5f, 0, 1,
0.5f, -0.5f, 0.5f, 1, 1,
0.5f, 0.5f, 0.5f, 1, 0,
0.5f, 0.5f, -0.5f, 0, 0,
0.5f, -0.5f, -0.5f, 0, 1,
0.5f, -0.5f, 0.5f, 1, 1,
0.5f, 0.5f, 0.5f, 1, 0,
-0.5f, 0.5f, -0.5f, 0, 0,
-0.5f, -0.5f, -0.5f, 0, 1,
-0.5f, -0.5f, 0.5f, 1, 1,
-0.5f, 0.5f, 0.5f, 1, 0,
-0.5f, 0.5f, 0.5f, 0, 0,
-0.5f, 0.5f, -0.5f, 0, 1,
0.5f, 0.5f, -0.5f, 1, 1,
0.5f, 0.5f, 0.5f, 1, 0,
-0.5f, -0.5f, 0.5f, 0, 0,
-0.5f, -0.5f, -0.5f, 0, 1,
0.5f, -0.5f, -0.5f, 1, 1,
0.5f, -0.5f, 0.5f, 1, 0
};
and indices
short[] indices = {
0, 1, 3, 3, 1, 2,
4, 5, 7, 7, 5, 6,
8, 9, 11, 11, 9, 10,
12, 13, 15, 15, 13, 14,
16, 17, 19, 19, 17, 18,
20, 21, 23, 23, 21, 22
};
This means that the 1st, 3rd and 5th row of indices have the wrong winding order. It has to be:
short[] indices = {
0, 3, 1, 3, 2, 1,
4, 5, 7, 7, 5, 6,
8, 11, 9, 11, 10, 9,
12, 13, 15, 15, 13, 14,
16, 19, 17, 19, 18, 17,
20, 21, 23, 23, 21, 22
};

heightmap terrain collision OpenGL

So I have rendered a terrain based on a heightmap. It's based on this tutorial that I followed - http://www.mbsoftworks.sk/index.php?page=tutorials&series=1&tutorial=8
Now I want to have my camera to be able to "walk" on the terrain and i'm unsure of how to actually do it. I have checked a lot of other examples and have gotten some hints for barycentric coordinates. But i'm unsure of how to implement it properly.
float Terrain::getY(int x, int z)
{
//return
}
void Terrain::createTerrain()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Setup heightmap
glGenVertexArrays(1, &uiVAOHeightmap); // Create one VAO
glGenBuffers(1, &uiVBOHeightmapData); // One VBO for data
glGenBuffers(1, &uiVBOIndices); // And finally one VBO for indices
glBindVertexArray(uiVAOHeightmap);
glBindBuffer(GL_ARRAY_BUFFER, uiVBOHeightmapData);
float fHeights[HM_SIZE_X*HM_SIZE_Y] =
{
10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f,
5.0f, 5.0f,5.0f, 10.0f, 10.0f, 10.0f,
5.0f, 5.0f, 5.0f, 10.0f, 10.0f, 10.0f,
5.0f, 5.0f, 10.0f, 10.0f, 10.0f, 10.0f,
10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f,
10.0f, 5.0f, 5.0f, 5.0f, 5.0f, 10.0f,
};
float fSizeX = 100.0f, fSizeZ = 100.0f;
for (int i = 0; i<HM_SIZE_X*HM_SIZE_Y;i++)
{
for (int j = 0; j < HM_SIZE_X*HM_SIZE_Y; j++)
{
float column = float(i%HM_SIZE_X), row = float(i / HM_SIZE_X);
vHeightmapData[i] = glm::vec3(
-fSizeX / 2 + fSizeX*column / float(HM_SIZE_X - 1), // X Coordinate
fHeights[i], // Y Coordinate (it's height)
-fSizeZ / 2 + fSizeZ*row / float(HM_SIZE_Y - 1) // Z Coordinate
);
}
}
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3)*HM_SIZE_X*HM_SIZE_Y, vHeightmapData, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glGenBuffers(1, &uiVBOIndices);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, uiVBOIndices);
int iIndices[] =
{
0, 6, 1, 7, 2, 8, 3, 9, 4, 10, 5, 11, 36,
6, 12, 7, 13, 8, 14, 9, 15, 10, 16, 11, 17, 36,
12, 18, 13, 19, 14, 20, 15, 21, 16, 22, 17, 23, 36,
18, 24, 19, 25, 20, 26, 21, 27, 22, 28, 23, 29, 36,
24, 30, 25, 31, 26, 32, 27, 33, 28, 34, 29, 35
};
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(iIndices), iIndices, GL_STATIC_DRAW);
glEnable(GL_PRIMITIVE_RESTART);
glPrimitiveRestartIndex(HM_SIZE_X*HM_SIZE_Y);
}
I also have a camera class where I call the getY function.
HM_SIZE_X and HM_SIZE_Y are both 6

OpenGL cube faces wrongly displayed [SFML 2.1]

I have a problem with OpenGL: the faces of my cube aren't properly drawn. I tried to disable face culling but it didn't change a thing. By the way, I use sfml 2.1. I also tried to change the indices order of my cube, but it only got worse. Let me show you pictures:
Here's the picture using my first set of indices:
Here's the picture using my second set of indices:
Here are my sets of indices:
GLfloat vertexData[NUM_VERTS * ELEM_PER_POS + NUM_VERTS * ELEM_PER_COLOR] = {
-1.0f, -1.0f, -1.0f, // 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, 0.0f, 0.0f, 1.0f, // Colors
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 1.0f, 0.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, 0.0f, 1.0f, 1.0f};
GLuint vertexIndices[NUM_INDICES] = { // first indices
0, 1, 2,
1, 2, 3,
0, 1, 4,
1, 4, 5,
2, 3, 6,
3, 6, 7,
0, 2, 4,
2, 4, 6,
1, 3, 5,
3, 5, 7,
4, 5, 6,
5, 6, 7};
/* GLuint vertexIndices[NUM_INDICES] = { //second indices
2, 1, 0,
2, 3, 1,
0, 1, 4,
1, 5, 4,
2, 3, 6,
3, 7, 6,
0, 2, 4,
2, 6, 4,
1, 3, 5,
3, 7, 5,
6, 5, 4,
6, 7, 4};*/