I am writing a code for 3D world to 2D projection and as i try to push back coordinates in my vectors it gives me this error that there is no matching function to call to std::vector.
#include <X11/Xlib.h>
#include "draw.h"
#include "points.h"
#include "unistd.h"
#include <math.h>
#include <vector>
void draw(Display* d, Window w, GC gc)
{
std::vector<float> xpoints;
xpoints.push_back (-1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0);
std::vector<float> ypoints;
ypoints.push_back (1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0);
std::vector<float> zpoints;
zpoints.push_back (-1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0);
for (;;)
{
XClearWindow(d, w);
for (unsigned int c = 0; c < xpoints.size(); c++)
{
XDrawLine(d, w, gc, xpoints.at(c), ypoints.at(c), xpoints.at(c+1), ypoints.at(c+1));
}
XFlush(d);
usleep(16666);
}
}
You cannot push multiple values at once using push_back:
xpoints.push_back (-1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0);
If you are using c++11 you should directly initialize your vector:
std::vector<float> xpoints{-1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0};
Just include the vector header:
#include <vector>
Related
I am new to OpenGL and Shaders.
I want to write a toon shader.
I have this OpenGL code:
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
float black[] = { 0.0, 0.0, 0.0, 1.0 };
float red[] = { 1.0, 0.0, 0.0, 1.0 };
float green[] = { 0.0, 1.0, 0.0, 1.0 };
float blue[] = { 0.0, 0.0, 1.0, 1.0 };
float white[] = { 1.0, 1.0, 1.0, 1.0 };
float lowAmbient[] = { 0.2, 0.2, 0.2, 1.0 };
float fullAmbient[] = { 1.0, 1.0, 1.0, 1.0 };
glMaterialfv(GL_FRONT, GL_AMBIENT, blue);
glMaterialfv(GL_FRONT, GL_DIFFUSE, blue);
glMaterialfv(GL_FRONT, GL_SPECULAR, white);
glMaterialf(GL_FRONT, GL_SHININESS, 128.0);
glLightfv(GL_LIGHT0, GL_AMBIENT, lowAmbient);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -9);
glRotatef(45, 1, 0, 0);
glRotatef(45, 0, 0, 1);
glBegin(GL_QUADS);
//front
glNormal3f(0.0, 0.0, -1.0);
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f(-1.0, -1.0, 1.0);
glVertex3f(1.0, -1.0, 1.0);
glVertex3f(1.0, 1.0, 1.0);
//back
glNormal3f(0.0, 0.0, 1.0);
glVertex3f(1.0, 1.0, -1.0);
glVertex3f(1.0, -1.0, -1.0);
glVertex3f(-1.0, -1.0, -1.0);
glVertex3f(-1.0, 1.0, -1.0);
//right
glNormal3f(1.0, 0.0, 0.0);
glVertex3f(1.0, 1.0, 1.0);
glVertex3f(1.0, -1.0, 1.0);
glVertex3f(1.0, -1.0, -1.0);
glVertex3f(1.0, 1.0, -1.0);
//left
glNormal3f(-1.0, 0.0, 0.0);
glVertex3f(-1.0, 1.0, -1.0);
glVertex3f(-1.0, -1.0, -1.0);
glVertex3f(-1.0, -1.0, 1.0);
glVertex3f(-1.0, 1.0, 1.0);
//top
glNormal3f(0.0, 1.0, 0.0);
glVertex3f(-1.0, 1.0, -1.0);
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f(1.0, 1.0, 1.0);
glVertex3f(1.0, 1.0, -1.0);
//bottom
glNormal3f(0.0, -1.0, 0.0);
glVertex3f(-1.0, -1.0, -1.0);
glVertex3f(-1.0, -1.0, 1.0);
glVertex3f(1.0, -1.0, 1.0);
glVertex3f(1.0, -1.0, -1.0);
glEnd();
//Swap back and front buffer
glutSwapBuffers();
}
void init()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glEnable(GL_DEPTH_TEST);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
float ambientLight[] = { 0.2,0.2,0.2,1.0 };
float diffuseLight[] = { 0.8,0.8,0.8,1.0 };
float specularLight[] = { 1.0,1.0,1.0,1.0 };
float lightPosition[] = { 0.5,0.5,0.0,1.0 };
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
}
My Shader Codes:
#shader vertex
#version 330 core
void main()
{
}
#shader fragment
#version 330 core
vec3 LightPosition = gl_LightSource[0].position;//I don't know this is true or not
vec3 Normal;//I don't know how to calculate
void main()
{
vec4 color1 = gl_FrontMaterial.diffuse + gl_FrontMaterial.specular +
gl_FrontMaterial.ambient;
vec4 color2;
float intensity = dot(LightPosition, Normal);
if (intensity > 0.95) color2 = vec4(1.0, 1.0, 1.0, 1.0);
else if (intensity > 0.75) color2 = vec4(0.8, 0.8, 0.8, 1.0);
else if (intensity > 0.50) color2 = vec4(0.6, 0.6, 0.6, 1.0);
else if (intensity > 0.25) color2 = vec4(0.4, 0.4, 0.4, 1.0);
else color2 = vec4(0.2, 0.2, 0.2, 1.0);
gl_FragColor = color1 * color2;
}
To calculate light intensity and apply colors to my cube object I should know normals.
How can I calculate, or if there is a way, reach them?
(I have no problem with the shader compilation, or other OpenGL stuff. If I close my shader compilation lines I can see a green cube.)
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 am making an apartment with C++ and openGl. I have made basic walls, roof and floor by just declaring points in the drawing function and everything of course works but code is messy and adding furniture this way would of course be very painful. So I am asking how should I organize my objects and format drawing function?
Here's the current code:
// Floor and roof of room 1
glBegin(GL_QUADS);
glNormal3f(0.0, 1.0, 0.0);
glColor3f(0.0, 1.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(1.0, 0.0, 0.0);
glVertex3f(1.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 1.0);
glNormal3f(0.0, -1.0, 0.0);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glVertex3f(1.0, 1.0, 1.0);
glVertex3f(0.0, 1.0, 1.0);
glEnd();
// Walls
glBegin(GL_QUAD_STRIP);
glNormal3f(1.0, 0.0, 0.0);
glColor3f(1.0, 1.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(0.0,0.0,1.0);
glVertex3f(0.0,1.0,1.0);
glNormal3f(0.0, 0.0, -1.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(1.0, 0.0, 1.0);
glVertex3f(1.0, 1.0, 1.0);
glNormal3f(-1.0, 0.0, 0.0);
glColor3f(0.5, 0.0, 0.5);
glVertex3f(1.0, 0.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glEnd();
And so on for room 2 and door spots..
Any places to read about this subject?
You can use 3d modelling software, e.g. →Blender to define your geometry etc. Then I recommend to use →Assimp to load the exported model. Also recommend to avoid the old fixed-function pipeline – write your own little scenegraph engine and manage your matrices and 3d math with →GLM
The following simple fragment shader exhibits very odd behaviour. Without the loop the output is all red, as expected. But with the loop it turns yellow, i. e. rgb(1,1,0). Might someone enlighten me as to what is happening here?
void main(void)
{
mat4 redUnit = mat4(
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
);
mat4 greenUnit = mat4(
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0
);
mat4 blueUnit = mat4(
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0
);
for (int x = -1; x < 3; x++) {
for (int y = -1; y < 3; y++) {
redUnit[x+1][y+1] = 1.0;
greenUnit[x+1][y+1] = 0.0;
blueUnit[x+1][y+1] = 0.0;
}
}
gl_FragColor = vec4(redUnit[0][0], greenUnit[0][0], blueUnit[0][0], 1.0);
}
EDIT: The output color depends on the order in which the variables are declared. So somehow memory boundaries are being violated. Still doesn't explain the behaviour though.
In case anyone else encounters this: It is a bug in the Intel GMA graphics driver. On another machine with a different graphics card everything works just fine.
Evening everyone,
I'm using glMultMatrixf in OpenGL to rotate my scene using the matrix:
float matrix[16] = { 1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0 };
I've been following this guide (link) but its a little bit over the top for what I need.
How could I simply rotate the x-axis by 45 degrees?
Cheers
Multiplying your transformation matrix by this rotation matrix should do the trick:
float rot45X[16] = { 1.0, 0.0, 0.0, 0.0,
0.0, cos(PI/4), -sin(PI/4), 0.0,
0.0, sin(PI/4), cos(PI/4), 0.0,
0.0, 0.0, 0.0, 1.0 };
Edit: You can also of course use the utility function
glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
where [x,y,z] indicate the axis of rotation (yes, it performs rotations around an arbitrary vector).
In your case you would need to call like this:
glRotatef(45, 1, 0, 0);