How to move object in world via glUniform**?
I tried glUniform3f(_positionSlot, 6.0f, 6.0f, -2.0f);
But my object not moving.
shader.vs:
attribute vec4 Position; // 1
attribute vec4 SourceColor; // 2
varying vec4 DestinationColor; // 3
uniform mat4 Projection;
uniform mat4 Modelview;
void main(void) { // 4
DestinationColor = SourceColor; // 5
gl_Position = Projection * Modelview *Position;
}
Reder:
- (void)render:(CADisplayLink*)displayLink {
glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
CC3GLMatrix *projection = [CC3GLMatrix matrix];
float h = 4.0f * self.frame.size.height / self.frame.size.width;
[projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:4 andFar:10];
glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix);
CC3GLMatrix *modelView = [CC3GLMatrix matrix];
[modelView populateFromTranslation:CC3VectorMake(sin(CACurrentMediaTime()), 0, -7)];
_currentRotation += displayLink.duration * 90;
[modelView rotateBy:CC3VectorMake(_currentRotation, _currentRotation, 0)];
glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix);
// 1
glViewport(0, 0, self.frame.size.width, self.frame.size.height);
// 2
glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 3));
glUniform4f(_colorSlot, 1.0f, 0.0f, 0.0f,1);
glDrawElements(GL_TRIANGLE_STRIP, 14, GL_UNSIGNED_SHORT, indices);
glUniform3f(_modelViewUniform, 6.0f, 6.0f, -2.0f);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer2);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
[_context presentRenderbuffer:GL_RENDERBUFFER];
}
EDIT:
_positionLocation=glGetAttribLocation(programHandle, "Translation");
glUniform3f(_positionLocation, -1.0f, 6.0f, -2.0f);
glDrawElements(GL_TRIANGLE_STRIP, 14, GL_UNSIGNED_SHORT, indices);
glUniform3f(_positionLocation, 1.0f, 6.0f, -2.0f);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer2);
If I draw only cube or only square all is ok. But seems that couple of it renders at same position and I see only cube. Seems that this method doesn't work.
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
gl_Position = Projection * Modelview * Position;
gl_Position is the vertex shader output that receives the transformed position of each vertex, not just the whole model. The "position slot" (varying/attribute) is used to pass vertex attribute data, namely each vertex position to the shader. You cannot apply a uniform to an attribute or varying. You need some additional uniform (let's call it "translation"):
attribute vec4 Position; // 1
attribute vec4 SourceColor; // 2
varying vec4 DestinationColor; // 3
uniform mat4 Projection;
uniform mat4 Modelview;
uniform vec4 Translation;
void main(void) { // 4
DestinationColor = SourceColor; // 5
gl_Position = Projection * Modelview * (Position + Translation);
}
Which you can set using with something like
glUniform3f(positionLocation, 6.0f, 6.0f, -2.0f);
BTW: Those are not called "slots", they're called "Locations".
Related
I need to draw graph.
I have to arrays of vertex attributes:
array of x coordinates: xPos
array of y coordinates: yPos
But X doesn't match Y.
I need to create separate arrays of indices and link them to the corresponding arrays of coordinates.
What i need
glEnableVertexAttribArray(opglp->xPositionLocation);
glBindBuffer(GL_ARRAY_BUFFER, opglp->vbo1);
glVertexAttribPointer(opglp->xPositionLocation, 1, GL_FLOAT, GL_FALSE, 0 , 0 );
glEnableVertexAttribArray(opglp->yPositionLocation);
glBindBuffer(GL_ARRAY_BUFFER, opglp->vbo2);
glVertexAttribPointer(opglp->yPositionLocation, 1, GL_FLOAT, GL_FALSE, 0 , 0 );
glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_SHORT, NULL);
Vertex shader:
attribute float xPosition;
attribute float yPosition;
uniform mat4 projection;
uniform mat4 modelView;
void main()
{
vec4 pos;
pos = vec4(xPosition, yPosition, 0.0, 1.0);
gl_Position = projection * modelView * pos;
}
I want to create a simple Cube of Lines in OpenGL and QT 5.5.
The Problem is, if I´m drawing a simple line to another Z-coordinate (from z -1.0f to z 1.0f), the line will look like it goes to z=infinity.
Vertex stackVerts[] = {
{QVector3D(-1.0f, -1.0f, 1.0f), // 0
QVector3D(+1.0f, +0.0f, +0.0f)}, // Colour
{QVector3D(1.0f, -1.0f, 1.0f), // 1
QVector3D(+0.0f, +1.0f, +0.0f)}, // Colour
{QVector3D(-1.0f, 1.0f, 1.0f), // 2
QVector3D(+0.0f, +0.0f, +1.0f)}, // Colour
{QVector3D(1.0f, 1.0f, 1.0f), // 3
QVector3D(+1.0f, +1.0f, +1.0f)}, // Colour
{QVector3D(-1.0f, -1.0f, -1.0f), // 4
QVector3D(+1.0f, +0.0f, +0.0f)}, // Colour
{QVector3D(1.0f, -1.0f, -1.0f), // 5
QVector3D(+0.0f, +1.0f, +0.0f)}, // Colour
{QVector3D(-1.0f, 1.0f, -1.0f), // 6
QVector3D(+0.0f, +0.0f, +1.0f)}, // Colour
{QVector3D(1.0f, 1.0f, -1.0f), // 7
QVector3D(+1.0f, +1.0f, +1.0f)}, // Colour
};
GLushort stackIndices[] = {
0,1,
1,3,
3,2,
2,0,
0,4,
};
...
glDrawElements(GL_LINES, 10, GL_UNSIGNED_SHORT, 0);
The Matrix is set a Uniform:
_transMatrix.setToIdentity();
_transMatrix.perspective(60.0f, (float)(width()/height()), 0.1f, 100.0f);
_transMatrix.translate(0, 0, -3);
_transMatrix.rotate(64,0,1,0);
_program.setUniformValue("transMatrix", _transMatrix);
The Vertex.glsl:
#ifdef GL_ES
// Set default precision to medium
precision mediump int;
precision mediump float;
#endif
attribute vec3 a_position;
attribute vec3 a_color;
uniform mat4 transMatrix;
varying vec3 theColor;
void main()
{
vec4 v = vec4 (a_position, 1.0);
gl_Position = v * transMatrix;
theColor = a_color;
}
The GL_DEPTH_TEST is enabled and if i change the translation of z to -1000, it will still go to infinity.
Translate z=-3
Translate z=-1000
I am writing a shader to draw lines with a width, as an alternative to glLineWidth, which doesn't work above 1.0 with ANGLE, and I'd like my lines to have the same thickness on Windows. I am running on desktop OpenGL for now, though.
The vertex shader source is as follows
attribute vec3 a_startPosition;
attribute vec3 a_endPosition;
attribute float a_choice;
attribute float a_dir;
uniform mat4 u_mvpMatrix;
uniform float u_width;
uniform vec2 u_viewDims;
void main()
{
vec4 start = u_mvpMatrix*vec4(a_startPosition, 1.0);
vec4 end = u_mvpMatrix*vec4(a_endPosition, 1.0);
//gl_Vertex;
vec2 slope = normalize(end.xy - start.xy);
slope = vec2(slope.y, -slope.x);
vec2 scale = u_width/u_viewDims;
if (a_choice == 0.0)
gl_Position = vec4(start.xy + a_dir*scale*slope.xy*start.w, start.zw);
else
gl_Position = vec4(end.xy + a_dir*scale*slope.xy*end.w, end.zw);
}
See that I have gl_Vertex, unused, commented out.
int width, height;
glfwGetFramebufferSize(m_window, &width, &height);
glUseProgram(m_shaders[Shader_WideLine]->id());
GLint shaderid = m_shaders[Shader_WideLine]->id();
GLint coloc = glGetUniformLocation(shaderid, "Color");
GLint dimloc = glGetUniformLocation(shaderid, "u_viewDims");
GLint widthloc = glGetUniformLocation(shaderid, "u_width");
GLint mvploc = glGetUniformLocation(shaderid, "u_mvpMatrix");
GLint modelviewloc = glGetUniformLocation(shaderid, "u_modelview");
GLint projloc = glGetUniformLocation(shaderid, "u_projection");
GLint dirloc = glGetAttribLocation(shaderid, "a_dir");
GLint startloc = glGetAttribLocation(shaderid, "a_startPosition");
GLint endloc = glGetAttribLocation(shaderid, "a_endPosition");
GLint chloc = glGetAttribLocation(shaderid, "a_choice");
//////////
//Set Uniforms
//////////
glUniform1f(widthloc, 10);
glUniform2f(dimloc, width, height);
glUniform4f(coloc, 0.101f, 0.558f, 0.109f, 1.f);
glm::mat4 modelview;
glm::mat4 projection;
glGetFloatv(GL_MODELVIEW_MATRIX, glm::value_ptr(modelview));
glGetFloatv(GL_PROJECTION_MATRIX, glm::value_ptr(projection));
glm::mat4 mvp = projection * modelview;
glUniformMatrix4fv(mvploc, 1, GL_FALSE, glm::value_ptr(mvp));
int numpts = 4;
GLfloat v[4][3] = {
{0,1,0},
{0,0,0},
{1,0,0},
{1,1,0}
};
//////////
// Draw (attributes)
//////////
glBegin( GL_TRIANGLE_STRIP );
glNormal3d(0.0, 0.0, 1.0);
for(int i=0; i<numpts-1; i++)
{
glVertexAttrib3fv(startloc, v[i]);
glVertexAttrib3fv(endloc, v[i+1]);
glVertexAttrib1f(chloc, 0);
glVertexAttrib1f(dirloc, -1.0f);
glVertex3d(0,0,0);
glVertexAttrib1f(dirloc, 1.0f);
glVertex3d(0,0,0);
glVertexAttrib1f(chloc, -1);
glVertexAttrib1f(dirloc, -1.0f);
glVertex3d(0,0,0);
glVertexAttrib1f(dirloc, 1.0f);
glVertex3d(0,0,0);
}
glEnd();
glUseProgram(0);
So I am trying to draw lines from (0,1,0) to (0,0,0) to (1,0,0) to (1,1,0) with a width of 10 pixels. In the following images is a wire cube 2x2x2 centered on the origin for reference.
When called as presented I get the unexpected result of this
If I uncomment gl_Vertex; in the shader, so that it is unused but referenced, I get this expected result.
What is the reason that this could happen?
gl_ModelViewProjectionMatrix is not a valid ES 2.0 vertex shader built-in variable.
You'll have to pass in your MVP via uniform.
Could I bind a vec2 array to a vec4 variable in shader language?
For example, in the code blow, the variable "position" is a vec4 type, and I tried to bind variable "squareVertices" to it, but squareVertices is a vec2 type array, only with (x,y) coodinates, maybe default (x,y,z,w) = (x,y,0,1)?
My Vertex shader and attribute bind code:
attribute vec4 position;
attribute vec2 textureCoordinate;
varying vec2 coordinate;
void main()
{
gl_Position = position;
coordinate = textureCoordinate;
}
glBindAttribLocation(gProgram, ATTRIB_VERTEX, "position");
glBindAttribLocation(gProgram, ATTRIB_TEXTURE, "textureCoordinate");
// bind attribute values
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_TEXTURE, 2, GL_FLOAT, 0, 0, coordVertices);
glEnableVertexAttribArray(ATTRIB_TEXTURE);
// squareVertices definition
static const GLfloat squareVertices[] = {
-1.0f, -1.0f,
0.0f, -1.0f,
-1.0f, 0.0f,
0.0f, 0.0f,
};
Yes, this is legal. And, you're correct that the default values of z and w are 0 and 1, respectively. This is covered in section 2.7 of the OpenGL ES 2.0 specification.
float pfIdentity[] =
{
-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,0.0f,0.0f,1.0f
};
==================================================================================
const char* pszVertShader = "\
attribute highp vec4 myVertex;\
uniform mediump mat4 myPMVMatrix;\
invariant gl_Position;\
void main(void)\
{\
gl_Position = myPMVMatrix * myVertex;\
}";
=====================================================================
for(int i = 0; i < 80000; ++i)
{
glClear(GL_COLOR_BUFFER_BIT);
int i32Location = glGetUniformLocation(uiProgramObject, "myPMVMatrix");
glUniformMatrix4fv( i32Location, 1, GL_FALSE, pfIdentity);
glEnableVertexAttribArray(VERTEX_ARRAY);
glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0,i);
eglSwapBuffers(eglDisplay, eglSurface);
}
return 0;
}
p.s : i am doing opengl-es in ubuntu 10.10 with kronos headers , its an emulator for opengl-es 2.0 in linux.
You don't have a projection at all. The Projection-Model-View matrix you're setting the myPMVMatrix uniform to is
float pfIdentity[] =
{
-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,0.0f,0.0f,1.0f
};
/* ... */
glUniformMatrix4fv( i32Location, 1, GL_FALSE, pfIdentity);
BTW: The idea of uniforms is, that you don't set them at each primitive iteration.
Anyway, this is a identity matrix, and since it's the only transformation applied it will just pass through the vertices as they are to the fragment stage. The solution for your problem is applying a orthographic projection to it, i.e. multiply that matrix with a ortho projection matrix and use the result of that operation instead. http://www.songho.ca/opengl/gl_projectionmatrix.html