Related
Context: Need to set verts in TestTextures3SpriteObj s1 to the verts1 array. Gives me an error "expression must be modifiable lvalue". After its copied the vertices will be sent to the GPU as buffer data with OpenGL and GLUT.
Only relevant excerpts of code included
#pragma once
class TestTextures3SpriteObj
{
public:
int spriteid;
int vao;
int texid;
float verts[];
};
const float verts1[] = { 0.5 ,0.5, 0.0, 0.9, 0.5, 0.3, 0.0, 1.0, 0.0,
0.5, -0.5, 0.0, 0.3, 0.3, 0.9, 1.0, 1.0, 1.0,
-0.5, -0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0,
-0.5, 0.5, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0 };
TestTextures3SpriteObj s1;
s1.verts = verts1;
Actually you are not accessing the variable ...
if you want access individual element, use index
s1.verts1[0]
If you want to copy use std::copy
std::copy(verts1, verts1 + 36, s1.verts);
#include <iostream>
using namespace std;
class TestTextures3SpriteObj
{
public:
int spriteid;
int vao;
int texid;
float verts[36]; //assign the size to the array
};
const float verts1[] = { 0.5 ,0.5, 0.0, 0.9, 0.5, 0.3, 0.0, 1.0, 0.0,
0.5, -0.5, 0.0, 0.3, 0.3, 0.9, 1.0, 1.0, 1.0,
-0.5, -0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0,
-0.5, 0.5, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0 };
int main()
{
TestTextures3SpriteObj s1;
int len=sizeof(verts1)/sizeof(verts1[0]);
//copies the entire array to the object with member verts
std::copy(verts1, verts1 + 36, s1.verts);
//printing the values in the s1 object
for(int i=0;i<len;i++)
{
cout<<s1.verts[i]<<" ";
}
}
Assign a size to the array in the class and then later perform the std::copy to copy the values in the verts array.
I have a code below in C++ OpenGL. It has six triangles that form hexagonal.
However, I need to be able to rotate it in vertically.
Can someone help? TNX
Details: I have six independent triangles with vertices. In addition, there is two-dimensional array that is used for colors.
There is a loop starts at line [here] two keep windows rendering until it is exited. Another line at line [here-two] that is used to show all the triangles with their color.
//coordinates of triangle
float triangle[6][9] = {
{
0.0, 0.0, 0.0,
-0.5, 0.87, 0.0,
0.5, 0.87, 0.0
},
{
0.0, 0.0, 0.0,
-0.5, -0.87, 0.0,
0.5, -0.87, 0.0
},
{
0.0, 0.0, 0.0,
0.5, 0.87, 0.0,
1.0, 0.0, 0.0
},
{
0.0, 0.0, 0.0,
0.5, -0.87, 0.0,
1.0, 0.0, 0.0
},
{
0.0, 0.0, 0.0,
-0.5, 0.87, 0.0,
-1.0, 0.0, 0.0
},
{
0.0, 0.0, 0.0,
-0.5, -0.87, 0.0,
-1.0, 0.0, 0.0
}
};
float color[][9]{
{
255, 0, 0,
255, 0, 0,
255, 0, 0
},
{
0, 255, 0,
0, 255, 0,
0, 255, 0
},
{
0, 0, 255,
0, 0, 255,
0, 0, 255
}
};
int count = 0;
/* Loop until the user closes the window */ [here] while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT);
[here-two] for (int i = 0; i < 6; i++)
{
//Render OpenGL here
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, triangle[i]);
glColorPointer(3, GL_FLOAT, 0, color[count]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
count++;
if (count > 2) count = 0;
}
//Swap front and back buffers
glfwSwapBuffers(window);
//Poll for and process events
glfwPollEvents();
// Poll for and process events
glfwPollEvents();
}
Read up on the use of matrices. What most games do in this case is they apply a matrix in the shader (as a uniform variable) that will rotate the object. In this case, you would create a rotation matrix of angle x, pass it to the shader, and then every new frame increment x and pass it to the shader again.
For more information on the specifics of the implementation read these:
https://www.opengl.org/wiki/Uniform_(GLSL) - Creating uniform
variables in a shader and updating them
http://inside.mines.edu/fs_home/gmurray/ArbitraryAxisRotation/ -
Creating a matrix that will rotate a vertex.
And a tip with matrix operations: remember to apply them in the right order. If you want to get the object to rotate around it's centre, make sure the rotation matrix is applied first and that the origin of your mesh is it's centre.
On my journey towards being competent at OpenGL, I was trying to make a textured cube when I came upon this problem:
Only part of my cube is being rendered. There should be 12 triangles but only 3 of them are being rendered. I've looked at many tutorials, but I can't seem to find the problem/main difference between our code. Here's mine:
...
int main(int argc, char* argv[]) {
if (!setupGLFW()) return 1;
setupApple();
glfwWindowHint(GLFW_SAMPLES, 4);
GLFWwindow* window = glfwCreateWindow(WIN_WIDTH, WIN_HEIGHT, "Textured Cube", NULL, NULL);
if (!window) {
log_msg(LOG_ERROR, "Could not open a GLFW3 window!\n");
return 1;
}
glfwMakeContextCurrent(window);
if (!setupGLEW()) return 1;
glClearColor(0.5, 0.5, 0.5, 1.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
static const int vertices = 12 * 3;
static const GLfloat points[] = {
-1.0, -1.0, -1.0,
-1.0, -1.0, 1.0,
-1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
-1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
1.0, -1.0, -1.0,
-1.0, -1.0, -1.0,
-1.0, -1.0, -1.0,
-1.0, 1.0, 1.0,
-1.0, 1.0, -1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, 1.0,
-1.0, -1.0, -1.0,
-1.0, 1.0, 1.0,
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
1.0, -1.0, -1.0,
1.0, 1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
-1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
1.0, -1.0, 1.0
};
static const GLfloat textureCoords[] = {
0, 0,
1, 0,
0, 1,
0, 1,
1, 0,
1, 1,
0, 0,
1, 0,
0, 1,
0, 1,
1, 0,
1, 1,
0, 0,
1, 0,
0, 1,
0, 1,
1, 0,
1, 1,
0, 0,
1, 0,
0, 1,
0, 1,
1, 0,
1, 1,
0, 0,
1, 0,
0, 1,
0, 1,
1, 0,
1, 1,
0, 0,
1, 0,
0, 1,
0, 1,
1, 0,
1, 1,
};
GLuint pointBuffer;
glGenBuffers(1, &pointBuffer);
glBindBuffer(GL_ARRAY_BUFFER, pointBuffer);
glBufferData(GL_ARRAY_BUFFER, vertices * 3, points, GL_STATIC_DRAW);
GLuint textureBuffer;
glGenBuffers(1, &textureBuffer);
glBindBuffer(GL_ARRAY_BUFFER, textureBuffer);
glBufferData(GL_ARRAY_BUFFER, vertices * 2, textureCoords, GL_STATIC_DRAW);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, pointBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, textureBuffer);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
GLuint program = getProgramFromFiles("text_cube.vs.glsl", "text_cube.fs.glsl");
glm::mat4 MVP = calculateMVP();
GLuint texture = loadBMP("uvtemplate.bmp");
if (!program) {
log_msg(LOG_ERROR, "There was a problem opening shader.\n");
// clean up
return 1;
}
if (!texture) {
log_msg(LOG_ERROR, "There was a problem opening shader.\n");
// clean up
return 1;
}
glUseProgram(program);
GLuint MVPID = glGetUniformLocation(program, "MVP");
GLuint textureID = glGetUniformLocation(program, "cube_texture");
glUniformMatrix4fv(MVPID, 1, GL_FALSE, &MVP[0][0]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(textureID, 0);
while (!glfwWindowShouldClose(window) && glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, vertices);
glfwPollEvents();
glfwSwapBuffers(window);
}
// clean up
return 0;
}
Just so you know, the error is not with setupGLFW(), setupApple(), setupGLEW(), getProgramFromFiles(), calculateMVP(), loadBMP(), or my vertex and fragment shaders, which are in different files. This compiles fine because I include GLFW and GLEW from myglutils.h This is uvtemplate.bmp, its a 512x512 image:
If you guys could help me, it would be greatly appreciated. Thanks!
The problem is the call to glBufferData(). You set the size in floats but you have to specify it in bytes using sizeof(GLfloat). That's why OpenGL isn't receiving all of your data.
void glBufferData
(
GLenum target,
GLsizeiptr size,
const GLvoid* data,
GLenum usage
);
So you need to replace:
glBufferData(GL_ARRAY_BUFFER, vertices * 3, points, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, vertices * 2, textureCoords, GL_STATIC_DRAW);
with:
glBufferData(GL_ARRAY_BUFFER, vertices * 3 * sizeof(GLfloat), points, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, vertices * 2 * sizeof(GLfloat), textureCoords, GL_STATIC_DRAW);
Is there an openGL function for creating a 3D cube using it's dimensions as input parameters?
If not what algorithm would i use for generating the cube's vertex array?
What would be the easiest way to create a cube that does not require calculating the vertex array by hand?
Create an unitary cube. It is very easy to create it:
It's vertexes are:
GLfloat vertex[] = { -1.0, -1.0, 1.0, // 0
1.0, -1.0, 1.0, // 1
1.0, 1.0, 1.0, // 2
-1.0, 1.0, 1.0, // 3
-1.0, -1.0, -1.0, // 4
1.0, -1.0, -1.0, // 5
1.0, 1.0, -1.0, // 6
-1.0, 1.0, -1.0}; // 7
Now, create an array of how the faces are connected. Using QUAD as exemple,
GLuint faces[] = { 0, 1, 2, 3,
1, 5, 6, 2,
5, 4, 7, 6,
7, 4, 0, 3,
3, 2, 6, 7,
0, 4, 5, 1 };
Let's say that you create a function, called cube(), in which you passed this coordinates to the driver.
Now, to have any kind of cube, just specify the scale transformation to transform this unitary cube. For example, to make a cube of 4 units:
scale(4.0, 4.0, 4.0);
cube();
and so on
I'm trying to depict a cube using a perspective projection, but all I get is the corner of a square. The face of the square is set at the origin and expands in the positive direction. Using glOrtho I can set the coordinate system, but I'm having trouble doing the same thing using glPerspective.
#include <gl/glut.h>
void mesh(void) {
float v[8][3] = { /* Vertices for 8 corners of a cube. */
{0.0, 0.0, 0.0}, {100.0, 0.0, 0.0}, {100.0, 100.0, 0.0}, {0.0, 100.0, 0.0},
{0.0, 0.0, -100.0}, {100.0, 0.0, -100.0}, {100.0, 100.0, -100.0}, {0.0, 100.0, -100.0} };
float n[6][3] = { /* Normals for the 6 faces of a cube. */
{0.0, 0.0, 1.0}, {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0},
{-1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}, {0.0, 0.0, -1.0} };
int f[6][4] = { /* Indexes of the vertices in v that make the 6 faces of a cube. */
{0, 1, 2, 3}, {1, 5, 6, 2}, {3, 2, 6, 7},
{0, 4, 7, 3}, {0, 1, 5, 4}, {4, 5, 6, 7} };
for (int j = 0; j < 6; j++) {
glBegin(GL_QUADS);
glNormal3fv(&n[j][0]);
glVertex3fv(&v[f[j][0]][0]);
glVertex3fv(&v[f[j][1]][0]);
glVertex3fv(&v[f[j][2]][0]);
glVertex3fv(&v[f[j][3]][0]);
glEnd();
glFlush();
}
}
void display(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
mesh();
}
void main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB |GLUT_DEPTH |GLUT_SINGLE);
glutInitWindowSize(400, 300);
glutInitWindowPosition(200, 200);
glutCreateWindow("Mesh");
glClearColor(0.0, 0.0, 0.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//glRotatef(15, 0.0, 0.0, 1.0);
//glOrtho(-400.0, 400.0, -300.0, 300.0, 200.0, -200.0);
gluPerspective(120,1,0,600);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glutDisplayFunc(display);
glutMainLoop();
}
You say you only see corners of the cube? Then your Field of view is too wide.. you are using gluPerspective() and providing your calculations are correct.. the values are a bit off imo, the function parameters are:
void gluPerspective(GLdouble fovy,
GLdouble aspect_ratio,
GLdouble zNear,
GLdouble zFar);
i propose changing that to something like
gluPerspective(45.0f,
width_of_window / height_of_window, //aspect ratio
0.1f,
500.0f);